标签: dynamic-script-loading

Require.js和在DOM中创建<script>元素有什么区别?

使用Require.JS和<script>在DOM中创建元素之间的区别是什么?

我对Require.JS的理解是它提供了加载依赖项的能力,但这不能简单地通过创建一个<script>加载必要的外部JS文件的元素来完成吗?

例如,假设我有函数doStuff(),这需要函数needMe().doStuff()在外部文件中do_stuff.js,而needMe()在外部文件中need_me.js.

这样做Require.JS方式:

define(['need_me'],function(){
    function doStuff(){
        //do some stuff
        needMe();
        //do some more stuff
    }
});
Run Code Online (Sandbox Code Playgroud)

只需创建一个脚本元素即可:

function doStuff(){
    var scriptElement  = document.createElement('script');
    scriptElement.src = 'need_me.js';
    scriptElement.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(scriptElement);

    //do some stuff
    needMe();
    //do some more stuff
}
Run Code Online (Sandbox Code Playgroud)

这两项都有效.但是,第二个版本不要求我加载所有Require.js库.我真的没有看到任何功能差异......

javascript dynamic-script-loading requirejs js-amd

138
推荐指数
3
解决办法
3万
查看次数

使用Modernizr.load(yepnope.js)导致我的脚本被请求两次的原因是什么

我使用yepnope.js动态加载javascript文件,我注意到我的脚本似乎根据Firebug和Webkit Inspector加载了两次.

问题是在Firebug的Net面板(Firefox 4最新版)中,他们的反应是200,而不是304.它似乎比Chrome慢.

我上传了这个显示问题的视频.您可以看到文件jquery-1.6.1.min.jslibs.js加载的时间.

我用来执行此操作的代码如下,简化:

Modernizr.load({
                load: ['jquery-1.6.1.min.js', 'libs.js'],
                complete: function () {
                    console.log("loaded");
                }
});
Run Code Online (Sandbox Code Playgroud)

Modernizr.load()yepnope().

javascript dynamic-script-loading modernizr yepnope

20
推荐指数
1
解决办法
6260
查看次数

包装器允许模块使用AMD/CommonJs或脚本标签?

我只是试图包装我们的一个模块,这些模块通过<script>一些样板中的标签包含在内,以允许可选的AMD加载requirejs.

这是非常痛苦的,我能想到的最好的是:

(function(){
var exports, jQuery;
if (typeof window.define === 'function' && typeof window.requirejs === 'function') {
    exports     = {};
    define(['jquery'], function (jq) {
        jQuery = jq;
        return thisModule();
    });
} else {
    exports     = window;
    jQuery      = window.jQuery;
    thisModule();
}


function thisModule() {
}

})();
Run Code Online (Sandbox Code Playgroud)

请注意,这是

  • 很多样板
  • 需要你在变量中声明依赖项(在这种情况下,谢天谢地只有jQuery)和amd
  • 如果我想拥有CommonJs支持,需要更多代码.

我主要关心的是第二点,因为当我超越包装我们的核心文件时,它将会变得很糟糕.我确定那里有一些整洁的(呃)包装器实现,但我找不到任何.

有人有任何提示吗?

javascript amd boilerplate commonjs dynamic-script-loading

16
推荐指数
1
解决办法
4182
查看次数

如何在RequireJS中混合Underscore插件?

在加载时,在Underscore上执行代码的正确方法是什么?我正在尝试执行以下代码,以便在模块需要时自动扩展_ exported namespace:

_.mixin(_.str.exports());
Run Code Online (Sandbox Code Playgroud)

文档有点模糊,但我想我把它放在shim init部分?我试过以下但是我甚至无法在init中获得一个断点:

require.config({
    paths: {
        jquery: 'libs/jquery/jquery.min',
        underscore: 'libs/underscore/lodash.min',
        underscorestring: 'libs/underscore/underscore.string.min'
    },

    shim: {
        underscore: {
            exports: '_'
        }
        underscorestring: {
            deps: ['underscore'],
            init: function (_) {
                //Mixin plugin to namespace
                _.mixin(_.str.exports());

                return _;
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

当我尝试这样做并使用underscorestring时,我收到此错误:

未捕获的TypeError:对象函数s(e){return new o(e)}没有方法'startsWith'

文档:

javascript asynchronous dynamic-script-loading requirejs underscore.js

11
推荐指数
1
解决办法
3915
查看次数

动态加载Web组件/ HTML导入?

您将如何动态加载Web组件 - 例如,响应URL路由更改?

我不会提前知道所请求的组件,所以你可以简单地使用JavaScript来编写HTML导入,然后将代码添加到页面中,或者是否有这样的含义?Google Polymer可能有帮助吗?

javascript html5 web-component dynamic-script-loading polymer

10
推荐指数
1
解决办法
9757
查看次数

为什么通过DOMParser创建的脚本元素不会执行?

我在Ajax中加载HTML,解析它DOMParser并将所有childNodes文档主体放入文档片段中.

当我将片段添加到当前文档的正文中时,<script>不会执行标记.

我摆弄并想出如果我用新动态创建的脚本标签替换它们,它们就会被正确执行.

我想知道为什么?

例如

var html = "Some html with a script <script>alert('test');</script>";

var frag = parsePartialHtml(html);


fixScriptsSoTheyAreExecuted(frag);


document.body.appendChild(frag);


function fixScriptsSoTheyAreExecuted(el) {
  var scripts = el.querySelectorAll('script'),
      script, fixedScript, i, len;

  for (i = 0, len = scripts.length; i < len; i++) {
    script = scripts[i];

    fixedScript = document.createElement('script');
    fixedScript.type = script.type;
    if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
    else fixedScript.src = script.src;
    fixedScript.async = false;

    script.parentNode.replaceChild(fixedScript, script);
  }
}


function parsePartialHtml(html) {
  var doc = …
Run Code Online (Sandbox Code Playgroud)

html javascript dynamic-script-loading

10
推荐指数
1
解决办法
1790
查看次数

具有多个包的Browserify的效率

我是Browserify的新手,我正在努力弄清楚如何使客户端需要下载的效率更高.

我有一个Web应用程序,它使用许多不同的第三方库和自定义代码.使用Browserify,似乎人们建议将一切都包装成一个大的一般方法bundle.js.由于以下几个原因,这对我来说似乎非常低效:

例如,让我们说你的bundle.js包含lib1, lib2, lib3, customLib.

  1. 如果您的网络应用程序的一部分只需要lib1客户端仍然必须下载巨大的bundle.js,它最终不使用75%的.已下载浪费的字节.不必要地增加了页面加载时间.
  2. 如果您customLib是经常迭代的代码,那么每次更改时,您的客户都必须重新下载bundle.js,再次下载大量未更改的第三方库...

您的网络应用程序的其他部分可能会使用lib2,lib3但客户端可能会或可能不会去那里,他绝对浪费带宽下载整个bundle.js.

我已经看到了将捆绑包分成多个捆绑包的建议.但到底是什么?如果一个页面使用lib1,其他页面使用lib1,并lib2和另一个页面使用lib2lib3,那么你如何分割它呢?你把它分成多个捆绑包的次数越多,你是不是会摆脱优势bundle.js

Browserify似乎受到高度重视,所以我希望我在这里错过了一些东西.将许多库和自定义脚本捆绑在一起的正确方法是什么?人们将Browserify称为"脚本加载器",但我过去看过的每个脚本加载器(如yepnope等)都使用逻辑来确定要下载的脚本,这似乎是一个更有效的解决方案,而Browserify似乎希望客户端能够下载一切......

javascript dynamic-script-loading browserify

8
推荐指数
1
解决办法
2547
查看次数

是否应该订购动态脚本?

<script>在页面加载后动态地向head元素添加了一些标签.我理解脚本是异步加载的,但是我可以期望它们按照添加的顺序进行解析吗?

我在Firefox中看到了预期的行为,但在Safari或Chrome中却没有.查看Chrome开发人员工具和Firebug中的文档,两者都显示以下内容 -

<html>
  <head>
    ...
    <script type="text/javascript" src="A.js"></script>
    <script type="text/javascript" src="B.js"></script>
  </head>
  ...
</html>
Run Code Online (Sandbox Code Playgroud)

但是,在查看资源加载视图时,chrome似乎会解析从服务器首先返回的任何一个,而firebug总是按照添加脚本标记的顺序加载它们,即使首先从服务器返回B也是如此.

我是否希望Chrome/Safari按指定顺序解析文件?在OS X 10.6.3上使用Chrome 5.0.375.29 beta

编辑(10/5/10):当我说解析时,我的意思是执行 - 可以看到积极解析的许多好处 - thx rikh

编辑(11/5/10):好的,所以我按照下面的juandopazo的说法进行了测试.但是我添加了一些东西,包括

  1. 使用javascript直接将脚本元素添加到头部.(测试A - > D)
  2. 使用jquery的append()方法将脚本元素添加到头部.(测试E - > H)
  3. 使用jquery的getScript()方法"加载"脚本.(测试I - > L)

我还尝试了脚本标签上"async"和"defer"属性的所有组合.

您可以在此处访问测试 - http://dyn-script-load.appspot.com/,并查看源代码以了解其工作原理.加载的脚本只需调用update()函数.

首先要注意的是,只有上述第一和第三种方法并行运行 - 第二种方法依次执行请求.你可以在这里看到这个图表 -

图1 - 请求生命周期
请求生命周期图表http://dyn-script-load.appspot.com/images/dynScriptGraph.png

有趣的是,jquery append()方法也阻止了getScript()调用 - 你可以看到它们都没有执行,直到所有append()调用完成,然后它们全部并行运行.关于这一点的最后一点是,jQuery append()方法在执行后显然会从文档头中删除脚本标记.只有第一种方法会在文档中保留脚本标记.

Chrome结果

结果是Chrome始终执行第一个要返回的脚本,无论测试如何.这意味着所有测试'失败',除了jQuery append()方法.

图2 - Chrome 5.0.375.29测试结果
Chrome结果http://dyn-script-load.appspot.com/images/chromeDynScript.png

Firefox结果

但是,在firefox上,如果使用第一个方法,并且async为false(即未设置),那么脚本将按顺序可靠地执行.

图3 - FF 3.6.3结果
FF结果http://dyn-script-load.appspot.com/images/ffDynScript.png

请注意,Safari似乎以与Chrome相同的方式提供不同的结果,这是有道理的.

此外,我在慢速脚本上只有500毫秒的延迟,只是为了保持开始 - >结束时间.您可能需要刷新几次才能看到Chrome和Safari在所有内容上都失败了.

在我看来,没有这样做的方法,我们没有利用并行检索数据的能力,并且我们没有理由不应该(如firefox所示).

javascript dynamic-script-loading

7
推荐指数
1
解决办法
1195
查看次数

如何规避RequireJS加载全局模块?

我正在尝试从书签中加载JS文件.JS文件有这个包装模块的JS:

(function (root, factory) {
    if (typeof module === 'object' && module.exports) {
        // Node/CommonJS
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals
        root.moduleGlobal = factory();
    }
}(this, function factory() {
    // module script is in here

    return moduleGlobal;
}));
Run Code Online (Sandbox Code Playgroud)

因此,如果网页使用RequireJS,则脚本在加载时不会导出全局.为了解决这个问题我暂时设置definenull,加载脚本,然后重置define为其原始值:

function loadScript(url, cb) {
    var s = document.createElement('script');
    s.src = url;
    s.defer = true; …
Run Code Online (Sandbox Code Playgroud)

javascript amd global-variables dynamic-script-loading requirejs

7
推荐指数
1
解决办法
967
查看次数

在 React 中使用 Spotify Web Playback SDK

Spotify 在测试版中有一项新功能,支持在浏览器中播放完整歌曲,即 Web Playback SDK。该文档显示了使用主 HTML 文件中的脚本标签立即初始化播放器的示例。这需要立即在脚本中设置访问令牌。我的问题是我正在创建一个 React 应用程序,如果用户单击按钮登录到他们的 Spotify 帐户,我只想初始化一个播放器。为了仅在发生此事件时才加载脚本,我使用了 react-load-script。我想要的流程是:用户单击按钮登录他们的 Spotify 帐户,一旦他们的登录通过 Spotify 的身份验证,我的应用程序就会收到一个访问令牌,然后加载网络播放脚本,一旦加载脚本,就会调用回调函数并且播放器使用访问令牌进行初始化。

问题是Spotify对象直到加载了spotify-player脚本才存在。当实际调用handleScriptLoad回调时,定义了Spotify对象,但是在编译代码时却没有。有没有人有任何想法如何解决这个问题?

来自相关 React 组件的代码示例:

import Script from 'react-load-script'

...

handleScriptLoad = () => {
const token = this.props.tokens.access
const player = new Spotify.Player({      // Spotify is not defined until 
  name: 'Spotify Web Player',            // the script is loaded in 
  getOAuthToken: cb => { cb(token) }
})

player.connect()
}

...
Run Code Online (Sandbox Code Playgroud)

在我的 React 组件的渲染方法中:

<Script 
  url="https://sdk.scdn.co/spotify-player.js" 
  onError={this.handleScriptError} 
  onLoad={this.handleScriptLoad}
/>
Run Code Online (Sandbox Code Playgroud)

javascript spotify dynamic-script-loading reactjs

7
推荐指数
1
解决办法
4340
查看次数