我想以这样一种方式挂钩document.createElement函数,每次我创建一个div元素时,我的钩子都会将一个“foo”属性附加到div。这就是我目前所拥有的:
<script>
window.onload = function () {
console.log("document loaded");
document.prototype.createElement = function (input) {
var div = document.createElement(input);
console.log("createElement hook attached!");
if (input == "div")div.foo = "bar";
return div;
}
document.body.addEventListener('onready', function () {
var div = document.createElement("div");
console.log(div.foo);
});
}
</script>
当我在Chrome中运行时,我收到错误消息
Uncaught TypeError: Cannot set property 'createElement' of undefined test.html:4 window.onload
(我更改了上面错误消息中的行号以匹配我的代码)
我错在哪里?我该如何解决这个问题?
答案 0 :(得分:9)
document
没有.prototype
,因为它是实例对象而不是构造函数document.createElement
,它最终会递归。你需要在某个地方存储对旧的引用,然后调用它。试试这个
document.createElement = function(create) {
return function() {
var ret = create.apply(this, arguments);
if (ret.tagName.toLowerCase() === "div") {
ret.setAttribute("foo", "bar");
}
return ret;
};
}(document.createElement)
答案 1 :(得分:1)
我建议不要覆盖现有功能,因为将来可能会将它们设为只读。我建议对DOM进行后期处理(div的快速遍历比拦截每个元素的创建更快)和/或修改插入div的代码以添加属性。或者,如果你真的想修改创建的节点,一个更好的方法是Mutation Observers(HTML5):
http://updates.html5rocks.com/2012/02/Detect-DOM-changes-with-Mutation-Observers
这比使用HTML4中已弃用的突变事件要好得多,除非您正在创建填充或填充,否则覆盖全局变量通常被认为是不好的做法。