首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在执行addEventListener()函数之前,请等待所有动态脚本源标记加载完毕

在执行addEventListener()函数之前,请等待所有动态脚本源标记加载完毕
EN

Stack Overflow用户
提问于 2021-06-23 09:01:28
回答 2查看 16关注 0票数 0

我的代码:

代码语言:javascript
复制
Util = {
    load_css : function(urls){

        for ( var i = 0; i < urls.length; i++){
            var head = document.head;
            var link = document.createElement("link");

            link.type = "text/css";
            link.rel = "stylesheet";
            link.href = urls[i];
            link.className = 'dynamic-css'

            head.appendChild(link);
        }

        document.querySelector('.dynamic-css').addEventListener('load', event => {
            Template.render();
        })
    },
    load_js : function(urls){

        for ( var i = 0; i < urls.length; i++){
            var script = document.createElement('script');
            script.setAttribute('src', urls[i]);
            script.setAttribute('class', 'dynamic-js');
            script.setAttribute('async', false);
            document.head.appendChild(script);
        }

        document.querySelector('.dynamic-js').addEventListener('load', event => {
            Template.render();
        })
    }
}

load_css和load_js的urls参数只是我想要加载的urls的数组(显然,load_js的js和load_css的css urls )。目前,我不认为addEventListener('load‘...)等待加载所有项;只加载一个。我如何让它等待所有的项目?

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-23 09:08:53

优化加载侦听器并使用Promise.all

代码语言:javascript
复制
Promise.all(
    urls.map((url) => {
        var script = document.createElement('script');
        script.setAttribute('src', url);
        script.setAttribute('class', 'dynamic-js');
        script.setAttribute('async', false);
        return new Promise((resolve, reject) => {
            script.addEventListener('load', resolve);
            script.addEventListener('error', reject);
            document.head.appendChild(script);
        });
    })
)
    .then(() => {
        Template.render();
    })
    .catch((error) => {
        // at least one script had an error
    });

实况演示:

代码语言:javascript
复制
const urls = [
  'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js',
  'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js'
];

Promise.all(
    urls.map((url) => {
        var script = document.createElement('script');
        script.setAttribute('src', url);
        script.setAttribute('class', 'dynamic-js');
        script.setAttribute('async', false);
        return new Promise((resolve, reject) => {
            script.addEventListener('load', resolve);
            script.addEventListener('error', reject);
            document.head.appendChild(script);
        });
    })
)
    .then(() => {
        console.log(typeof $);
        console.log(typeof _);
    })
    .catch((error) => {
        // at least one script had an error
    });

票数 1
EN

Stack Overflow用户

发布于 2021-06-23 09:32:51

如果顺序很重要,这将按顺序加载每个脚本(而不是整个批),这就是为什么它们是单独的promises与promiseAll的原因

代码语言:javascript
复制
const scripts = [
  "https://somewhere.com/scripts/script1.js",
  "https://somewhere.com/scripts/script2.js",
  "https://somewhere.com/scripts/script3.js",
  "https://somewhere.com/scripts/script4.js"
];

let sctr = 0;
const doScript = () => {
  if (sctr++ >= scripts.length) {
    console.log('all scripts loaded');
    Template.render();
    return;
  }
  const scriptPromise = new Promise((resolve, reject) => {
    const script = document.createElement('script');
    document.body.appendChild(script);
    script.onload = resolve;
    script.onerror = reject;
    script.async = true; // they're loading one at a time, so async is ok
    script.src = scripts[sctr];
  });

  scriptPromise.then(() => {
      console.log(scripts[sctr], 'loaded');
      doScript();
    },
    (err) => {
      console.error(scripts[sctr], 'failed', err);
      // halting
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68092300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档