问题描述
我想将来自 CDN 的 jQuery 包含到我的代码中。我也想创建一个后备。我最初的解决方案是检查 CDN 是否失败,如果失败,则使用 document.write
将后备 <script>
插入 DOM
。
现在 Google saying 不使用 document.write
,因此我更改了回退函数以将本地 <script>
路径动态插入到 DOM
中:
<script>
function fallback(id,localScript) {
fallBackNode = document.getElementById(id);
// insert local jQuery path,right after fallback (does not work)
fallBackNode.insertAdjacentHTML("afterend","<script src='" + localScript + "'><\/script>");
// insert local jQuery path,(works)
//document.write('<script src="' + localPath + '"><\/script>');
}
</script>
// jQuery CDN
<script src="https://code.jquery.com/jquery-3.6.0.9-INVALID_CDN.min.js"></script>
// jQuery fallback
<script id="jqueryfallback">window.jQuery || fallback('jqueryfallback','/Scripts/jquery-3.6.0.min.js');
// jQuery ui CDN
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script></script>
上述两个选项(即使用 document.write
和使用 fallBackNode.insertAdjacentHTML
)产生完全相同的结果,它们在回退检查后立即插入我的本地路径,如下所示:
<script id="jqueryfallback">window.jQuery || fallback('jqueryfallback','/Scripts/jquery-3.6.0.min.js');</script>
<script src="/Scripts/jquery-3.6.0.min.js"></script> // <-- both solutions insert this line here
但是,当我使用 document.write
时,一切正常,并且本地 jQuery 在 jQuery.ui 之前加载......但是如果我使用 fallBackNode.insertAdjacentHTML
选项,我会在 jQuery.ui 中收到以下错误:
看起来,下一个库 jQuery.ui 没有等待本地 jQuery 插入到 DOM 中,并抛出错误......我该如何解决这个问题?
解决方法
我对这个想法很感兴趣,所以我尝试了一个简单的脚本加载顺序。您可以按照希望加载的顺序设置主/后备脚本数组。不确定它的生产准备情况,但如果有帮助,请告诉我。
const scripts = [{
main: "https://badlink.com/nothing.js",fallback: "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
},{
main: "https://badlink.com/nothing.js",fallback: "https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
}
];
let scriptcounter = 0;
function loadScripts() {
if (scriptcounter < scripts.length) {
loadScript(scriptcounter);
}
}
function loadScript(index,fallback) {
let thescript = fallback ? scripts[index].fallback : scripts[index].main
let myScript = document.createElement("script");
myScript.setAttribute("src",thescript);
document.body.appendChild(myScript);
myScript.addEventListener("load",scriptLoaded,false);
myScript.addEventListener("error",scriptError,false);
function scriptError() {
console.log("Script error for ",thescript);
if (fallback) console.log("Fallback failed,stopping");
else loadScript(index,true)
}
function scriptLoaded() {
console.log("Script loaded - ",thescript);
scriptcounter++;
loadScripts()
}
}
window.onload = function() {
loadScripts()
}