使用函数原型挂钩document.createElement

时间:2012-07-30 18:52:56

标签: javascript

我想以这样一种方式挂钩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

(我更改了上面错误消息中的行号以匹配我的代码)

我错在哪里?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:9)

  • document没有.prototype,因为它是实例对象而不是构造函数
  • 你在新函数中调用新的document.createElement,它最终会递归。你需要在某个地方存储对旧的引用,然后调用它。
  • 您正在设置属性而不是属性
  • 这是非常脆弱的事情,不能保证工作。它似乎适用于chrome和firefox,但在旧的IE中不起作用

试试这个

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)

http://jsfiddle.net/NgxaK/2/

答案 1 :(得分:1)

我建议不要覆盖现有功能,因为将来可能会将它们设为只读。我建议对DOM进行后期处理(div的快速遍历比拦截每个元素的创建更快)和/或修改插入div的代码以添加属性。或者,如果你真的想修改创建的节点,一个更好的方法是Mutation Observers(HTML5):

http://updates.html5rocks.com/2012/02/Detect-DOM-changes-with-Mutation-Observers

这比使用HTML4中已弃用的突变事件要好得多,除非您正在创建填充或填充,否则覆盖全局变量通常被认为是不好的做法。