You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拦截修改动态加载script标签innerHTML后,如何同步至DOM原生属性?

解决HTMLScriptElement的innerHTML拦截与原始值保存问题

问题分析

你已经成功拦截了script标签的innerHTML赋值操作,但之前的两种尝试都存在问题:

  • 直接修改HTMLElement.prototype.innerHTML:此时this指向的是HTMLElement.prototype而非当前的script实例,不符合DOM属性的调用上下文要求,因此触发"illegal invocation"错误。
  • 直接修改HTMLScriptElement.prototype.innerHTML:会递归触发你自定义的setter,导致栈溢出("Maximum call stack size exceeded")。

正确实现方式

核心思路是先保存原始的innerHTML setter,再在自定义setter中调用它并传入修改后的值,同时确保调用时绑定当前的script实例作为上下文:

// 保存HTMLElement原型上的原始innerHTML setter
const originalInnerHTMLSetter = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerHTML').set;

// 重新定义HTMLScriptElement的innerHTML属性
Object.defineProperty(HTMLScriptElement.prototype, "innerHTML", {
    set: function (value) {
        // 修改赋值内容
        const modifiedValue = value + 1;
        console.log(modifiedValue);
        // 调用原始setter,绑定当前实例作为this
        originalInnerHTMLSetter.call(this, modifiedValue);
    },
    // 保留原始getter,确保读取时能拿到正确值
    get: Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerHTML').get
});

验证效果

执行以下测试代码:

const o = document.createElement('script');
o.innerHTML = 1;
console.log(o.innerHTML); // 输出"2",在DOM中查看该script标签内容也会显示"2"

这样既完成了赋值操作的拦截与修改,又能将修改后的值正确保存到DOM元素中,同时规避了之前的错误。

内容的提问来源于stack exchange,提问作者Gianluca De Stefano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 00:45:05