等待动态加载的脚本

时间:2011-09-05 13:38:43

标签: javascript jquery html load-order

在我的页面体中,我需要插入此代码作为AJAX调用的结果:

    <p>Loading jQuery</p>
    <script type='text/javascript' src='scripts/jquery/core/jquery-1.4.4.js'></script>
    <p>Using jQuery</p>
    <script type='text/javascript'>
        $.ajax({
            ...
        });
    </script>

我无法使用$.load(),因为文档已经加载,因此事件不会触发。

这样安全吗?如果没有,如何在执行自定义生成的代码之前确保已加载jquery脚本。

6 个答案:

答案 0 :(得分:29)

非常安全。从历史上看,<script>标记是完全阻塞的,因此在前者完成解析/排除之前,不能遇到第二个<script>标记。唯一的问题可能是“现代”浏览器倾向于异步加载脚本并延迟。因此,为确保订单正确,请按以下方式使用:

<p>Loading jQuery</p>
<script type='text/javascript' async=false defer=false src='scripts/jquery/core/jquery-1.4.4.js'></script>
<p>Using jQuery</p>
<script type='text/javascript'>
    $.ajax({
        ...
    });
</script>

然而,使用动态脚本标记插入而不是将其作为HTML字符串推送到DOM中可能更好。将是同一个故事

var scr  = document.createElement('script'),
    head = document.head || document.getElementsByTagName('head')[0];
    scr.src = 'scripts/jquery/core/jquery-1.4.4.js';
    scr.async = false; // optionally

head.insertBefore(scr, head.firstChild);

答案 1 :(得分:27)

在脚本文件中添加ID,以便查询。

<script id="hljs" async src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js"></script>

然后在JavaScript中添加一个加载侦听器

<script>
  var script = document.querySelector('#hljs');
  script.addEventListener('load', function() {
    hljs.initHighlightingOnLoad(); 
  });
</script>

答案 2 :(得分:9)

jQuery 1.6中还有新功能。它被称为jQuery.holdReady()。它实际上是自我解释的;当您致电jQuery.holdReady(true)时,ready事件在您致电jQuery.holdReady(false)之前不会被触发。将此设置为false不会自动触发就绪事件,只会删除保留。

以下是加载从文档中获取的脚本的非阻塞示例:

$.holdReady(true);
$.getScript("myplugin.js", function() {
     $.holdReady(false);
});

有关详细信息,请参阅http://api.jquery.com/jQuery.holdReady/

答案 3 :(得分:2)

select i.* 
  from reqd_items i 
       left join items_by_id d on i.item = d.item
 where d.item is null

动态添加脚本后将加载

答案 4 :(得分:1)

等待加载多个脚本

以下帮助程序仅加载一次多个脚本并返回promise:

async function cirosantilli_load_scripts(script_urls) {
    function load(script_url) {
        return new Promise(function(resolve, reject) {
            if (cirosantilli_load_scripts.loaded.has(script_url)) {
                resolve();
            } else {
                var script = document.createElement('script');
                script.onload = resolve;
                script.src = script_url
                document.head.appendChild(script);
            }
        });
    }
    var promises = [];
    for (const script_url of script_urls) {
        promises.push(load(script_url));
    }
    await Promise.all(promises);
    for (const script_url of script_urls) {
        cirosantilli_load_scripts.loaded.add(script_url);
    }
}
load_scripts.loaded = new Set();

(async () => {
    await cirosantilli_load_scripts([
        'https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js',
        'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js',
    ]);

    // Now do stuff with those scripts.

})();

GitHub上游:definitionusage

在Chromium 75中进行了测试。

答案 5 :(得分:-1)

$ .ajax和$ .load是一回事。你可以使用其中之一。如果你将$ .load放在页面上的脚本标记中,它会在加载时触发,就像$ .ajax()一样。

当你在做某事之前等待脚本开火时,Tomalak说这是真的。异常是异步调用。 Javascript将进行AJAX调用,然后继续运行脚本,当AJAX调用响应时,它将根据您告诉它的操作运行成功/失败。

现在说你希望你的JS等待返回,只需一次调用就可以很容易地将成功回调中的所有内容包装起来,或者你可以用很酷的方式完成并使用$ .deferred。这允许你制作一堆ajax调用或一个,然后只在完成后运行一些代码。

$。when&amp; $ .then可能是最好的情况。

你正在做的事情是安全的。