script元素修改src后onload仅触发一次,此为浏览器正常行为吗?
为什么修改已添加的script元素src时onload仅触发一次?
这是浏览器的正常行为
你没操作错,这就是浏览器对script元素的默认处理逻辑。
原因分析
- script元素的核心设计是加载执行一次后,就不会再响应src的修改。哪怕你给src加了时间戳参数,只要这个script元素已经在DOM里,浏览器就不会重新发起请求,自然也不会触发onload事件——浏览器认为这个脚本已经被处理过了。
- iframe则是完全不同的机制:它对应一个独立的浏览上下文,每次修改src都会重新加载整个嵌入页面,所以onload事件会每次都触发。
可行的解决方案
如果需要每次点击都加载带新参数的脚本并触发onload,有两种常用方法:
1. 每次创建新的script元素
每次点击时移除旧的script,创建全新的元素绑定onload后加入DOM:
function loadScript() { // 清理旧脚本 const oldScript = document.getElementById('dynamic-script'); if (oldScript) oldScript.remove(); // 创建新脚本 const script = document.createElement('script'); script.id = 'dynamic-script'; script.src = `https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?call_number=${Date.now()}`; script.onload = () => console.log('Loaded'); document.querySelector('head').appendChild(script); }
按钮代码改成:
<button onclick="loadScript()">点击多次都能加载脚本</button>
2. 用Fetch手动加载并执行脚本
通过Fetch API获取脚本内容,再注入到页面中执行,这种方式更灵活:
async function loadScript() { try { const res = await fetch(`https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?call_number=${Date.now()}`); const scriptText = await res.text(); const script = document.createElement('script'); script.textContent = scriptText; script.onload = () => console.log('Loaded and executed'); document.querySelector('head').appendChild(script); // 可选:执行完就移除,避免DOM冗余 setTimeout(() => script.remove(), 0); } catch (err) { console.error('加载失败:', err); } }
内容的提问来源于stack exchange,提问作者Andrei
相关产品推荐
相关产品推荐

