不使用append或添加到DOM,计算含script标签元素的宽度
不使用append计算元素宽度且避免script提前执行的解决方案
核心思路
要在不触发script执行的前提下计算元素宽度,核心是先隔离script标签,在离线DOM环境中完成尺寸计算,最后再恢复script并挂载元素。
具体实现步骤
- 暂存并移除script标签:先从目标div里提取所有script元素,把它们的内容和属性复制保存,再从div中删除原script,避免后续操作触发执行
- 创建离线计算容器:生成一个绝对定位且移出视口的容器,这个容器不会显示在页面上,但能正常计算内部元素的尺寸
- 计算目标宽度:把移除script后的div放进离线容器,读取
offsetWidth或getBoundingClientRect().width获取准确宽度 - 恢复script并挂载元素:把暂存的script放回div,根据计算出的宽度调整父元素尺寸,最后将div挂载到页面
代码示例
// 假设这是AJAX获取到的HTML内容 const ajaxHtml = '<div><script>alert("Testing");console.log("Duplicate");</script></div>'; // 1. 解析HTML到临时DOM const tempDiv = document.createElement('div'); tempDiv.innerHTML = ajaxHtml; // 2. 提取并暂存script标签 const savedScripts = []; const scriptNodes = tempDiv.querySelectorAll('script'); scriptNodes.forEach(script => { const scriptCopy = document.createElement('script'); scriptCopy.textContent = script.textContent; // 复制script的所有属性(比如src、type等) Array.from(script.attributes).forEach(attr => { scriptCopy.setAttribute(attr.name, attr.value); }); savedScripts.push(scriptCopy); script.remove(); // 从临时div中移除原script,避免执行 }); // 3. 创建离线计算容器 const calcWrapper = document.createElement('div'); calcWrapper.style.cssText = 'position: absolute; left: -9999px; top: -9999px; visibility: hidden;'; document.body.appendChild(calcWrapper); // 4. 放入临时div并计算宽度 calcWrapper.appendChild(tempDiv); const targetWidth = tempDiv.offsetWidth; // 或用 tempDiv.getBoundingClientRect().width // 5. 移除离线容器 calcWrapper.remove(); // 6. 恢复script标签到原div savedScripts.forEach(script => tempDiv.appendChild(script)); // 7. 调整父元素宽度并挂载到页面 const parent = document.getElementById('your-parent-element'); parent.style.width = `${targetWidth}px`; parent.appendChild(tempDiv);
补充说明
- 不要直接把带script的div放到页面任何容器(哪怕设置
display:none或visibility:hidden),只要挂载到document,script就会立即执行 - 若尝试用
DocumentFragment做离线计算,部分浏览器可能无法正确返回元素尺寸,兼容性不如上述方案
内容的提问来源于stack exchange,提问作者Bhavana
相关产品推荐
相关产品推荐

