JS 拦截、修改并保存属性赋值

问题描述 投票:0回答:2

我想记录并修改页面中所有动态加载的脚本标签的innerHTML属性分配的值。

为此,我想出了以下代码:

Object.defineProperty(HTMLScriptElement.prototype, "innerHTML", {
    set: function (value) {
        console.log(value + 1)
    }
});

加载到页面后,出现以下说明:

o = document.createElement('script');
o.innerHTML = 1;

将打印“2”,因此,我可以“拦截”并成功修改分配。

但是,我不知道将结果保存到父原型中定义的原始innerHTML变量中:

HTMLElement
,以便通过DOM检查时脚本的主体实际上将包含show
2

我已经尝试过:

Object.defineProperty(HTMLScriptElement.prototype, "innerHTML", {
    set: function (value) {
        HTMLElement.prototype.innerHTML = value +1;
    }
});

但这会导致“非法调用”错误。

同时:

Object.defineProperty(HTMLScriptElement.prototype, "innerHTML", {
    set: function (value) {
        HTMLScriptElement.prototype.innerHTML = value +1;
    }
});

结果:“超出最大调用堆栈大小”。

如何将修改后的值赋给父原型的innerHTML属性?

javascript dom
2个回答
0
投票

没关系,我已经找到解决方案了:

const originalInnerHTMLDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');

// Step 2: Define custom setter.
Object.defineProperty(HTMLScriptElement.prototype, 'innerHTML', {
    // Define the setter
    set: function(value) {
        const modifiedValue = value + 1;

        // Call the original setter.
        originalInnerHTMLDescriptor.set.call(this, modifiedValue);
    },

    get: function() {
        return originalInnerHTMLDescriptor.get.call(this);
    }
});

0
投票

这里有2个问题,

innerHTML
setter 和 getter 属于
Element.prototype

HTMLScriptElement.prototype
继承这些访问器,但不拥有它们。

您尝试仍然保留

innerHTML
功能的方法
不起作用,因为您正在更改类的原型
而不是更改实例
innerHTML

为此,您需要首先保存原始的

innerHTML
setter 函数

const innerHTMLSetter = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML').set

Object.defineProperty(Element.prototype, 'innerHTML', {
  set(value) {
    if (this instanceof HTMLScriptElement) {
      console.log(value + 1)
      innerHTMLSetter.call(this, value + 1)
      return
    }

   innerHTMLSetter.call(this, value)
  }
})
© www.soinside.com 2019 - 2024. All rights reserved.