24

クロスブラウザを起動するJQueryまたはバニラJavascriptにDOMミューテーションイベントはありますか?

明確にするために、divを本文に挿入するスクリプトがページにあるとします。スクリプトにアクセスできず、divがいつ挿入されたかわかりません。要素がいつ挿入されたかを知るために、リスナーを追加できるDOMミューテーションイベントがあるかどうか疑問に思いました。タイマーを使用して挿入を定期的にチェックできることは知っていますが、これによって発生するオーバーヘッドはあまり好きではありません。

4

6 に答える 6

24

これは確かにハックですが、ノードを挿入するために使用される基礎となる DOM メソッドにパッチを当ててみませんか? これを行うには、いくつかの方法があります。

A. _ 特定の要素が追加されることはわかっています。

var c = document.getElementById('#container');
c.__appendChild = c.appendChild;
c.appendChild = function(){
     alert('new item added');
     c.__appendChild.apply(c, arguments); 
}

A のフィドル デモ

B. _ どのタイプの要素が追加されるかはわかっています。

HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild;
HTMLDivElement.prototype.appendChild = function(){
    alert('new item added');
    HTMLDivElement.prototype.__appendChild(this,arguments); 
}

Bのフィドルデモ

(ソリューションBは、IE < 8または DOM プロトタイプをサポートしていない他のブラウザーではサポートされていないことに注意してください。)

これと同じ手法をinsertBeforereplaceChildやなどのすべての基になる DOM ミューテーション関数で簡単に使用できますremoveChild

それが一般的な考え方です。これらのデモは、他のほとんどすべてのユースケースに適応できます。たとえば、広いネットをキャストして、タイプに関係なくすべての追加をキャッチし、すべてのブラウザー動作することを確認したいとします。(下記の例 C を参照)IE < 8


アップデート

C. DOM を再帰的にウォークし、すべての要素の関数を交換してコールバックをトリガーし、追加されるすべての子に同じパッチを適用します。

var DOMwatcher = function(root, callback){
  var __appendChild = document.body.appendChild;

  var patch = function(node){
    if(typeof node.appendChild !== 'undefined' && node.nodeName !== '#text'){
      node.appendChild = function(incomingNode){
        callback(node, incomingNode);
        patch(incomingNode);
        walk(incomingNode);
        __appendChild.call(node, incomingNode);
      };
    }
    walk(node);  
  };

  var walk = function(node){
    var i = node.childNodes.length;
    while(i--){
      patch(node.childNodes[i]);
    }
  };

  patch(root);

};

DOMwatcher(document.body, function(targetElement, newElement){ 
   alert('append detected');    
});

$('#container ul li').first().append('<div><p>hi</p></div>');
$('#container ul li div p').append('<a href="#foo">bar</a>');

Cのフィドル デモ

更新 2

ティム・ダウンがコメントしたように、上記のソリューションは、 ではなく、またはをサポートしていないため、 では機能しませIE < 8ん。もし. _appendChildFunctioncallapplysetIntervaltypeof document.body.appendChild !== 'function'

于 2011-10-13T04:58:49.517 に答える
8

Chrome 14 と IE9 では、やなどの非推奨のDOM ミューテーション イベントがいくつかあります。DOMNodeInsertedDOMNodeInsertedIntoDocument

http://jsfiddle.net/Kai/WTJq6/で例を参照してください。

http://www.w3.org/TR/DOM-Level-3-Events/で W3C ドラフトのすべてを参照してください。

于 2011-10-11T20:34:35.573 に答える
4

JCADE (JQuery Create and Destroy Events) がこれを行います。IEの動作と、他のブラウザーのDOM ミューテーション イベントを使用します。タイミング イベントを使用せず、livequery のような JQuery メソッドをラップしません。

https://github.com/snesin/jcade

    $( ドキュメント ).create( "a", function( イベント ) {
      アラート(イベント.ターゲット);
    });

于 2012-02-22T16:43:08.557 に答える
3

プラグインがないわけではないと思いますが、間違っていても驚かないでしょう。

私の調査では、選択できるものがいくつか見つかりました。

これが1つです:http://plugins.jquery.com/project/mutation-events

ここに別のものがあります:https://www.adaptavist.com/display/jQuery/Mutation+Events

于 2011-10-07T20:51:41.797 に答える
0

この方法に代わる方法を探している場合は、http://www.jqui.net/jquery-projects/jquery-mutate-official/を参照してください。これにより、イベントを自分で追加して、ほぼすべての変更を監視することもできます。 、クラス名の変更、高さの変更、幅の変更。

于 2012-09-20T09:02:46.927 に答える