我想记录并修改页面中所有动态加载的脚本标签的innerHTML属性分配的值。
为此,我想出了以下代码:
Object.defineProperty(HTMLScriptElement.prototype, "innerHTML", {
set: function (value) {
console.log(value + 1)
}
});
加载到页面后,出现以下说明:
o = document.createElement('script');
o.innerHTML = 1;
将打印“2”,因此,我可以“拦截”并成功修改分配。
但是,我不知道将结果保存到父原型中定义的原始innerHTML变量中:
HTMLElement
,以便通过DOM检查时脚本的主体实际上将包含show2
。
我已经尝试过:
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属性?
没关系,我已经找到解决方案了:
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);
}
});
这里有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)
}
})