UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

164 lines (162 loc) 5.55 kB
var addScript = function addScript(script) { var _a; // Get the first script element, we're just going to use it // as a reference for where to insert ours. Do NOT try to do // this just once at the top and then re-use the same script // as a reference later. Some weird loaders *remove* script // elements after the browser has executed their contents, // so the same reference might not have a parentNode later. var firstScript = document.getElementsByTagName('script')[0]; // Append the script to the DOM, triggering execution. (_a = firstScript === null || firstScript === void 0 ? void 0 : firstScript.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(script, firstScript); }; /** * 以 Callback 的方式加载 js 文件 * @param {String} src js文件路径 * @param {Function|Object} callback 加载回调 * @param {String} charset 指定js的字符集 * @param {Object} context Callback context */ var loader = function loader(src, callback, charset, context) { if (charset === void 0) { charset = 'utf-8'; } if (context === void 0) { context = null; } var setup; if (callback && typeof callback !== 'function') { context = callback.context || context; setup = callback.setup; callback = callback.callback; } var done = false; var err; var privateCleanup; // _must_ be set below. /** * Final handler for error or completion. * * **Note**: Will only be called _once_. * * @returns {void} */ var privateFinish = function privateFinish() { // Only call once. if (done) { return; } done = true; // Internal cleanup. privateCleanup === null || privateCleanup === void 0 ? void 0 : privateCleanup(); // Callback. if (callback) { callback.call(context, err); } }; /** * Error handler * * @returns {void} */ var privateError = function privateError() { err = new Error(src || 'EMPTY'); privateFinish(); }; var curScript = document.querySelector("script[src=\"".concat(src, "\"]")); if (curScript) { var tc_1 = setInterval(function () { if (curScript.isready) { // 判断js加载完成 privateFinish(); clearInterval(tc_1); } }, 20); } else { var script_1 = document.createElement('script'); script_1.isready = false; if (script_1.readyState && !('async' in script_1)) { var isReady_1 = { loaded: true, complete: true }; var inserted_1 = false; // Clear out listeners, state. privateCleanup = function privateCleanup() { script_1.onreadystatechange = null; script_1.onerror = null; }; // Attach the handler before setting src, otherwise we might // miss events (consider that IE could fire them synchronously // upon setting src, for example). script_1.onreadystatechange = function () { var firstState = script_1.readyState; // Protect against any errors from state change randomness. if (err) { return; } if (!inserted_1 && isReady_1[firstState]) { inserted_1 = true; // Append to DOM. addScript(script_1); } if (firstState === 'loaded') { // The act of accessing the property should change the script's // `readyState`. // // And, oh yeah, this hack is so hacky-ish we need the following // eslint-disable-next-line @typescript-eslint/no-unused-expressions script_1.children; if (script_1.readyState === 'loading') { // State transitions indicate we've hit the load error. // // **Note**: We are not intending to _return_ a value, just have // a shorter short-circuit code path here. return privateError(); } } // It's possible for readyState to be "complete" immediately // after we insert (and execute) the script in the branch // above. So check readyState again here and react without // waiting for another onreadystatechange. if (script_1.readyState === 'complete') { script_1.isready = true; privateFinish(); } }; // Onerror handler _may_ work here. script_1.onerror = privateError; // call the setup callback to mutate the script tag if (setup) { setup.call(context, script_1); } // This triggers a request for the script, but its contents won't // be executed until we append it to the DOM. script_1.src = src; // In some cases, the readyState is already "loaded" immediately // after setting src. It's a lie! Don't append to the DOM until // the onreadystatechange event says so. } else { // This section is for modern browsers, including IE10+. // Clear out listeners. privateCleanup = function privateCleanup() { script_1.onload = null; script_1.onerror = null; }; script_1.onerror = privateError; script_1.onload = function () { script_1.isready = true; privateFinish(); }; script_1.async = true; script_1.charset = charset || 'utf-8'; // call the setup callback to mutate the script tag if (setup) { setup.call(context, script_1); } script_1.src = src; // Append to DOM. addScript(script_1); } } }; export { loader };