5

div要素を作成するたびに、フックが「foo」属性をdivにアタッチするように、document.createElement関数にフックしたいと思います。これは私が現在持っているものです:

<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

(上記のエラーメッセージの行番号をコードと一致するように変更しました)

私はここで何が間違っていますか?どうすればこれを修正できますか?

4

2 に答える 2

11
  • document.prototypeコンストラクター関数ではなくインスタンスオブジェクトであるため、はありません
  • 新しい関数でnewを呼び出すと、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/

于 2012-07-30T18:57:56.060 に答える
1

将来的には読み取り専用になる可能性があるため、既存の関数を上書きしないことをお勧めします。DOMを後処理する(divのクイックトラバーサルは、すべての要素の作成をインターセプトするよりも高速です)、および/またはdivを挿入するコードを変更して属性を追加することをお勧めします。あるいは、作成されたノードを本当に変更したい場合は、Mutation Observers(HTML5)がはるかに優れた方法です。

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

これは、HTML4で非推奨になっているミューテーションイベントを使用するよりもはるかに優れたオプションであり、シムまたはポリフィルを作成しない限り、グローバルを上書きすることは一般に悪い習慣と見なされます。

于 2012-07-30T19:10:46.657 に答える