Javascript 异步脚本加载回调
我已经创建了一个简短的函数,它如下所示:Javascript 异步脚本加载回调,javascript,function,asynchronous,callback,Javascript,Function,Asynchronous,Callback,我已经创建了一个简短的函数,它如下所示: function async(src) { var d = document, t = 'script', o = d.createElement(t), s = d.getElementsByTagName(t)[0]; o.src = '//' + src; s.parentNode.insertBefore(o, s); } 这非常有效,我已经开始在几个不同的脚本中使用它 // Crazy Egg async(
function async(src) {
var d = document, t = 'script',
o = d.createElement(t),
s = d.getElementsByTagName(t)[0];
o.src = '//' + src;
s.parentNode.insertBefore(o, s);
}
这非常有效,我已经开始在几个不同的脚本中使用它
// Crazy Egg
async('dnn506yrbagrg.cloudfront.net/pages/scripts/XXXXX/XXXXX.js?' + Math.floor(new Date().getTime() / 3600000));
// User Voice
var uvOptions = {};
async('widget.uservoice.com/XXXXX.js');
// Google Analytics
var _gaq = [['_setAccount', 'UA-XXXXX-XX'], ['_setDomainName', 'coachup.com'], ['_trackPageview']];
async('google-analytics.com/ga.js');
// Stripe
async('js.stripe.com/v1');
当我遇到加载后需要调用的脚本时,就会出现问题:
// Snap Engage
async('snapabug.appspot.com/snapabug.js');
SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');
所以我想我应该把它转换成一个回调函数,可以这样使用:
async('snapabug.appspot.com/snapabug.js', function() {
SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');
});
我没想到这对我来说会很难做到,但事实证明是这样的
我的问题是,在不过度复杂代码的情况下,添加回调最有效的方法是什么。
请参阅JSFIDLE:
谢谢你
带回调的异步函数:
用法:
async('snapabug.appspot.com/snapabug.js', function() {
SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');
});
最近的一个片段:
async function loadAsync(src) {
const script = document.createElement('script');
script.src = src;
return new Promise((resolve, reject) => {
script.onreadystatechange = function () {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
resolve(true);
}
};
document.getElementsByTagName('head')[0].appendChild(script);
});
}
利用
loadAsync(`https://....js`).then(_ => {
// ... script loaded here
})
没有考虑IE9。这是我找到的代码的修改版本。修改var baseUrl,以便它可以相应地找到脚本
//for requiring a script loaded asynchronously.
function loadAsync(src, callback, relative){
var baseUrl = "/resources/script/";
var script = document.createElement('script');
if(relative === true){
script.src = baseUrl + src;
}else{
script.src = src;
}
if(callback !== null){
if (script.readyState) { // IE, incl. IE9
script.onreadystatechange = function() {
if (script.readyState === "loaded" || script.readyState === "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function() { // Other browsers
callback();
};
}
}
document.getElementsByTagName('head')[0].appendChild(script);
}
利用率:
loadAsync('https://www.gstatic.com/charts/loader.js' , function(){
chart.loadCharts();
});
// OR relative path
loadAsync('fastclick.js', null, true);
其他答案很好,但不是非常可读或需要承诺。这是我的两分钱:
function loadScript(src, callback) {
var script = document.createElement('script');
script.setAttribute('src', src);
script.addEventListener('load', callback);
document.head.appendChild(script);
},
线
o.u='/'+u代码>应为o.src='/'+u代码>否则它不会加载一个字节。缩小有时会很棘手。s.addEventListener应该是o.addEventListener我认为这需要更多的逻辑来处理IE8和之前的问题,请参见示例:我认为此解决方案更全面,并且还包括一个承诺
实现:糟糕的变量名称很好的工作&感谢您给出了很好的答案。只需将函数最后一行中的“doc”更改为“document”。
function loadScript(src, callback) {
var script = document.createElement('script');
script.setAttribute('src', src);
script.addEventListener('load', callback);
document.head.appendChild(script);
},