UNPKG

cgreact-loader

Version:

CGReact与Webpack配套的loader

74 lines (73 loc) 2.55 kB
/** 当页面同时加载2个JSONP标签的时候 * 浏览器会随机选择某一个标签先执行,造成JS执行乱序问题 * 所以定义一个同步队列,保证JS的执行顺序按照用户调用的顺序 */ const SyncJSLoad = { loadFlag: false, jsTagQue: new Array(), start: () => { // 正在加载或者队列里没有需要加载的,就不管了 if (SyncJSLoad.loadFlag || SyncJSLoad.jsTagQue.length <= 0) { // 如果是正在加载JS,会在onload的时候重新调用此方法 return; } // 否则继续按顺序加载 SyncJSLoad.loadFlag = true; document.body.appendChild(SyncJSLoad.jsTagQue.shift()); } } // 开始构建返回结果 let script = cg_exports; let result = {}; result.script = script; /** JS的加载方式与CSS相比是不同的 * 即使是同一个CSS的<link>标签对象,只要被放置在页面上css就会生效,所以只需控制好一个标签的添加删除 * JS的<script>标签则不同,如果是同一个标签,只会在第一次放到页面上的时候执行JS代码,第二次则不会 * 因此必须每一次都创建一个新的<script>标签,移除的时候,也要考虑多次加载的问题(多次加载的标签是不同的对象) */ result.affect = (context) => { // 如果加载过首先移除,防止连续调用affect()出现多个相同标签(不同对象) result.invalid(); // 用jsonp的方式加载 let tag = document.createElement("script"); tag.setAttribute("type", "text/javascript"); tag.setAttribute("id", script); tag.setAttribute("src", script); tag.onload = function () { SyncJSLoad.loadFlag = false; SyncJSLoad.start(); } // 唤醒队列加载标签 SyncJSLoad.jsTagQue.push(tag); SyncJSLoad.start(); // 重载上下文钩子做自动移除 if (context) { result.bind(context); } return result; }; result.invalid = () => { let tag = document.getElementById(script); while (tag) { tag.remove(); tag = document.getElementById(script); } return result; }; // 重载上下文的钩子函数,做离开页面自动移除的效果 result.bind = (context) => { if (context && context.CssAndJSList && typeof context.CssAndJSList.push == "function") { context.CssAndJSList.push(result); } return result; }; module.exports = result;