【问题标题】:Calling javascript in javascript works for some but not all scripts在 javascript 中调用 javascript 适用于某些但并非所有脚本
【发布时间】:2021-01-20 01:12:17
【问题描述】:

我在我的 html 文件中调用的 script.js 文件中有以下代码:

function loadScript(url)
{    
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    script.async = false;
    head.appendChild(script);
}

loadScript('https://polyfill.io/v3/polyfill.min.js?features=es6')
loadScript('https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js')
loadScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js')

hljs.initHighlightingOnLoad();

我使用此代码是因为我只想在我的 html 中调用一个 .js 文件,而不是多个 .js 文件。

我加载调用MathJax 的前两个脚本工作正常。但是调用highlight.js 的第三个脚本没有运行。

当我将文件“highlight.min.js”中的所有代码粘贴到我的 script.js 文件中时,当我打开 html 时,javascript 确实运行正常。

我不明白为什么用 loadScript() 加载“highlight.min.js”文件不起作用,或者我可以做些什么来让它工作。任何帮助表示赞赏。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    脚本加载是异步的,所以当hljs.initHighlightingOnLoad()被调用时,脚本还没有加载。

    备选方案 1

    您可以修改您的 loadScript() 函数以使其与 Promise 一起使用,该 Promise 会在脚本加载时解决 (taken from here):

    function loadScript(url) {    
        return new Promise(function(resolve, reject) {
            var script = document.createElement("script");
            script.onload = resolve;
            script.onerror = reject;
            script.src = url;
            document.getElementsByTagName("head")[0].appendChild(script);
        });
    }
    

    现在您可以调用您的代码并确保在调用hljs.initHighlightingOnLoad()之前加载了所有库:

    (async function init() {
      await loadScript('https://polyfill.io/v3/polyfill.min.js?features=es6');
      await loadScript('https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js')
      await loadScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js')
      
      hljs.initHighlightingOnLoad();
    })()
    

    备选方案 2

    您可以修改您的loadScript() 函数,使其使用defer 加载脚本,并添加一个可选的onload 处理程序,您可以使用该处理程序调用hljs.initHighlightingOnLoad()

    function loadScript(url, onload)
    {    
        var head = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        script.async = false;
        script.onload = onload;
        head.appendChild(script);
    }
    
    loadScript('https://polyfill.io/v3/polyfill.min.js?features=es6')
    loadScript('https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js')
    loadScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js', () => {hljs.initHighlightingOnLoad()})
    

    【讨论】:

    • 嗯,为什么我需要一个 promise,我可以只在我的脚本元素上使用 async 属性吗?
    • 感谢您的帮助。我显然做错了什么,因为将您的代码复制到我的 script.js 文件中不起作用,但是当我将以下行添加到我的 html 时,highlight.js 运行正常::
    • @Jay 你是对的,你可以使用async = false 来延迟加载,然后你可以使用onload 处理程序来调用该函数。我会将此选项添加到答案中。
    • 谢谢你,但你的答案永远不会像我的一样好:) siek nah
    【解决方案2】:

    您的 onload 处理程序在哪里?

    script.onload = function(){};
    

    暂时不用担心错误...

    https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement

    如果库相互需要,那么您需要推迟,因为子级可能比父级小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      相关资源
      最近更新 更多