【问题标题】:How can I wait for <script> appended to body to finish executing如何等待附加到正文的 <script> 完成执行
【发布时间】:2020-08-02 11:23:39
【问题描述】:

当用户单击按钮时,我需要在我的正文中附加一个外部脚本。这是要求。

菜鸟问题。假设外部库创建了一个 window.newLib 变量。当 newLib 变量可供我使用时如何通知我?

我试过了,但没有调用 onload:

  const script = document.createElement('script');
  script.innerHTML = 'window.test = 1; console.log("test defined.");';
  script.onload = "console.log('onload called.', window.test)"
  script.async = false;
  document.body.appendChild(script);

这可行,但对我来说似乎很脏。有没有更好的办法?

const injectScript = () => {
  const script = document.createElement('script');
  script.innerHTML = 'setTimeout(() => {window.test = 1},10500); console.log("test defined.");';
  script.async = false;
  document.body.appendChild(script);
}

const nap = ms => new Promise(res => setTimeout(res, ms));

const maxAttempts = 100;
const msNap = 100; // 10s timeout

const start = async () => {
  injectScript();
  let id = 0;
  while (true) {
    if (++id === maxAttempts) {
      throw(`Lib took too long to load: ${id * msNap}ms`);
    }
    if (window.test) break;
    await nap(msNap);
  }
  console.log('External lib correctly loaded.');
};
start();

【问题讨论】:

  • script.onload = "console.log('onload called.', window.test)" 是错误的。这需要分配一个函数,而不是一个字符串。
  • 换句话说,script.onload = () =&gt; console.log('onload called.', window.test)
  • 真@Ultimater,但即使我这样做也不会被触发。
  • 为什么不把你的&lt;script src='yourJavaScriptPage.js'&gt;&lt;/script&gt;标签放在你的&lt;head&gt;中,只使用load事件呢?
  • 因为要求是后面需要加载。更多上下文:它是一个 Cordova 应用程序,所需的库作为按需资源从 Apple 服务器下载。不幸的是,我无法改变这一点。

标签: javascript html async-await script-tag ios-web-app


【解决方案1】:

感谢@Ultimater。这似乎按预期工作:

const script = document.createElement('script');
script.src = 'data:text/html,id = 0;while(true){ if(++id==1000000) break;} window.test = 1; console.log("test defined.");';
script.onload = () => console.log('onload called.', window.test);
document.body.appendChild(script);

【讨论】:

    【解决方案2】:

    试试这个:

    const injectScript = () => {
            const script = document.createElement('script');
            script.innerHTML = 'console.log("Function loaded..."); window.postMessage({cmd:"loaded"});';
            script.async = false;
            document.body.appendChild(script);
            }
    
            setTimeout(injectScript, 3000);
    
            window.addEventListener('message', function(e){
                if(e.data.cmd === 'loaded'){
                    console.log('external library loaded');
                }
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多