如何区分HTML源码中的<script>元素与JS动态加载的脚本?
区分HTML初始脚本与动态加载脚本的几种方法
以下是几种可行的JavaScript实现方案,覆盖不同场景:
方法一:DOMContentLoaded时记录初始脚本节点
页面DOM解析完成(DOMContentLoaded触发)时,HTML源码中包含的所有脚本节点已被加载到DOM中,之后新增的脚本必然是动态加载的。
// 存储初始脚本节点的集合 let initialScripts = new Set(); // 在DOM解析完成时记录所有已存在的脚本 document.addEventListener('DOMContentLoaded', () => { initialScripts = new Set(document.querySelectorAll('script')); }); // 判断指定脚本是否为HTML初始脚本 function isInitialScript(scriptNode) { return initialScripts.has(scriptNode); }
使用示例:
// 在页面加载后期遍历所有脚本并判断类型 document.querySelectorAll('script').forEach(script => { const scriptLabel = script.src || '内联脚本'; console.log(scriptLabel, isInitialScript(script) ? '是初始脚本' : '是动态加载脚本'); });
方法二:用MutationObserver监听动态脚本添加
从页面加载初期启动DOM变化监听,捕获所有后续动态插入的<script>节点,通过反向对比判断初始脚本。
const dynamicScripts = new Set(); // 配置监听:监听整个文档树的节点添加事件 const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { // 过滤出新增的脚本节点 if (node.tagName?.toLowerCase() === 'script') { dynamicScripts.add(node); } }); }); }); // 启动监听 observer.observe(document.documentElement, { childList: true, subtree: true }); // 判断脚本是否为动态加载 function isDynamicScript(scriptNode) { return dynamicScripts.has(scriptNode); }
该方法能实时捕获所有动态脚本,即使脚本在页面加载过程中被插入也能准确记录。
方法三:针对外部脚本的资源发起者判断
对于带src的外部脚本,可利用浏览器性能API,通过资源的发起者类型区分:HTML初始加载的外部脚本发起者类型为html;由JavaScript动态加载的脚本发起者类型为script。
function isDynamicExternalScript(scriptNode) { if (!scriptNode.src) return false; // 匹配对应资源的性能条目 const resourceEntry = performance.getEntriesByType('resource').find(entry => { return entry.name === scriptNode.src; }); // 发起者为script则是动态加载 return resourceEntry?.initiatorType === 'script'; }
注意:该方法仅适用于外部脚本,内联脚本需结合前两种方法判断。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

