創建script元素
var script = document.createElement('script');
document.head.appendChild(script); // insert into the <head></head> tag
script.addEventListener('load', ev => { // when the js execute done
// ...
});
script.src = '/foo.js'; // start execute a js, can delay
示例
index.tsx
import './index.html';
import * as ReactDOM from 'react-dom';
import ohMyJs from '!file-loader!./oh~my~js.js';
ReactDOM.render((
<div>
<h1 id="load">未加載JS</h1>
<button onClick={() => {
var script = document.createElement('script');
document.head.appendChild(script);
script.addEventListener('load', (ev) => {
document.getElementById('load').innerText = `計算完畢,F(${window.MAX}) = ${window.FMAX}`;
});
setTimeout(() => {
script.src = ohMyJs;
document.getElementById('load').innerText = '腳本執行中';
}, 200); // 可以超時設置src,但僅第一次賦值有效
}}>
動態加載JS,計算斐波拉契數列
</button>
</div>
), /* container */ document.querySelector('#app'));
oh~my~js.js
console.log('on~my~js 加載中');
function F(n) {
if (n < 2) return 1;
return F(n - 1) + F(n - 2);
}
window.MAX = 42;
for (var i = 0; i < MAX; i++) {
console.log(i, window.FMAX = F(i));
}
console.log('on~my~js 加載完畢');
通用解決方案
/**
* 動態注入腳本,並監聽執行完畢事件
* @param {string} src
* @param {() => void} onload
*/
function injectJS(src, onload) {
var loaded = Array.from(document.scripts).some(it => it.getAttribute('src') === src); // Warn:script.src !== script.getAttribute('src')
if (loaded) {
typeof onload === 'function' && onload();
return;
}
var script = document.createElement('script');
script.src = src;
document.head.insertBefore(script, document.head.firstElementChild);
script.addEventListener('load', (ev) => {
typeof onload === 'function' && onload();
});
}
END