仅在尚未加载 js 脚本时才加载它,然后仅加载一次

新手上路,请多包涵

我一直试图只加载一次大的 js 脚本。我不会在页面加载时加载它,因为那时不需要它并且会减慢页面加载速度。

所以我一直在尝试使用 jQuery 的 $.getScript 和 Modernizr.load 来加载它(因为我已经在使用 Modernizr 了)。

我已经尝试遍历所有 <script></script> 元素并检查它们的 src 属性并查看此脚本是否是其中之一,但每次我运行测试时仍然加载它们。

我还尝试在脚本的开头将全局变量设置为 true 并检查它是否已设置并且每次检查时它仍然加载。这是我在那种情况下所做的:

 Modernizr.load({
    test:if(window.flag === undefined),
    yep:'conversation.js',
    callback:function(){
        antecedent();
    }
});

并且 var flag = true; 被设置在 conversation.js 的第一行

有谁知道如何在调用此测试以检查它是否已加载并仅加载一次时让此脚本加载一次?

\*\* 编辑/更新:\*\* document.getElementsByTagName('head')[0].appendChild(document.createElement('sc‌​ript')).src = 'conversation.js'; 可以工作,但我如何检查脚本是否已经加载,然后仅在尚未包含脚本时调用它?

原文由 wordSmith 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 381
2 个回答

首先,您需要检查脚本是否已在页面上:

 var list = document.getElementsByTagName('script');
var i = list.length, flag = false;
while (i--) {
    if (list[i].src === 'filePathToJSScript') {
        flag = true;
        break;
    }
}

// if we didn't already find it on the page, add it
if (!flag) {
    var tag = document.createElement('script');
    tag.src = 'filePathToJSScript';
    document.getElementsByTagName('body')[0].appendChild(tag);
}

条件中的代码可用于向页面动态添加脚本。

ES 6 更新

ES 6 对此进行了相当大的简化:

 let scripts = Array
    .from(document.querySelectorAll('script'))
    .map(scr => scr.src);

if (!scripts.includes('filePathToJSScript')) {
  // same as above
}

原文由 Jared Smith 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是一个小函数,它将脚本标记添加到文档并在加载后执行回调。只有当脚本不存在时才会添加该脚本。

 export const loadScript = (url, callback) => {
    let script;
    const scripts = Array.from(document.querySelectorAll('script'));
    const existingScript = scripts.find((script) => script.src === url);
    if (existingScript) {
        script = existingScript;
    } else {
        script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        document.getElementsByTagName('head')[0].appendChild(script);
    }

    if (script.readyState) {
        script.onreadystatechange = () => {
            if (script.readyState === 'loaded' || script.readyState === 'complete') {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {
        script.onload = () => callback();
    }
};

原文由 Raúl 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题