web-dev-qa-db-ja.com

新しい要素を作成するための突然変異オブザーバー

特定のdivが作成されたときに関数をオフにしようとしています。簡単に言えば、私はこのようなものを持っています:

<a href="" id="foo">Click me!</a>
<script>
$("#foo").live("click",function(e) {
    e.preventDefault();
    $(this).append($("<div />").html("new div").attr("id","bar"));
});
</script>

以前は、変異イベントでdiv#barの作成をリッスンしていました-このようなもの:

$("#bar").live("DOMNodeInserted", function(event) {
    console.log("a new div has been appended to the page");
});

変異オブザーバーを使用して同等のものはありますか?私はattrchange.jsの機能を試しました DOM要素のスタイルオブジェクトが変更された後にJavaScriptフックトリガーを使用できますか? プラグインは、要素が作成されたときではなく、変更されたときのみ検出します。

34
Jimmy Ha

これは、_#foo_の子リストでミューテーションをリッスンし、barというIDの子が追加されているかどうかを確認するコードです。

_MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

$("#foo").live("click",function(e) {
    e.preventDefault();
    $(this).append($("<div />").html("new div").attr("id","bar"));
});

// define a new observer
var obs = new MutationObserver(function(mutations, observer) {
    // look through all mutations that just occured
    for(var i=0; i<mutations.length; ++i) {
        // look through all added nodes of this mutation
        for(var j=0; j<mutations[i].addedNodes.length; ++j) {
            // was a child added with ID of 'bar'?
            if(mutations[i].addedNodes[j].id == "bar") {
                console.log("bar was added!");
            }
        }
    }
});

// have the observer observe foo for changes in children
obs.observe($("#foo").get(0), {
  childList: true
});
_

ただし、これは_#foo_のみを監視します。他のノードの新しい子として_#bar_の追加を探す場合は、obs.observe()への追加の呼び出しでこれらの潜在的な親を監視する必要があります。 bazというIDのノードを観察するには、次のようにします。

_obs.observe($('#baz').get(0), {
  childList: true,
  subtree: true
});
_

subtreeオプションの追加は、オブザーバーが_#bar_の追加を子またはより深い子孫(孫など)として探すことを意味します。

31
apsillers

JQueryを使用する場合、以下に示すように MutationObserver sの使用を簡略化できます。

_$("#btnAddDirectly").click(function () {
    $("#canvas").append($('<span class="stuff">new child direct</span>'));
});
$("#btnAddAsChildOfATree").click(function () {
    $("#canvas").append($('<div><div><span class="stuff">new child tree</span></div></div>'));
});

var obs = new MutationObserver(function(mutations, observer) {
  // using jQuery to optimize code
  $.each(mutations, function (i, mutation) {
    var addedNodes = $(mutation.addedNodes);
    var selector = "span.stuff"
    var filteredEls = addedNodes.find(selector).addBack(selector); // finds either added alone or as tree
    filteredEls.each(function () { // can use jQuery select to filter addedNodes
      alert('Insertion detected: ' + $(this).text());
    });
  });
});

var canvasElement = $("#canvas")[0];
obs.observe(canvasElement, {childList: true, subtree: true});_
_<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="canvas">
Canvas
</div>

<button id="btnAddDirectly">Add span directly to canvas</button>
<button id="btnAddAsChildOfATree">Add span as child of a tree</button>_

常に注意することが重要です。.observe()MutationObserverInitの2番目の引数は重要です。

オプションで、spanを直接の子としてのみ追加する場合は、_childList: true_を使用します。 _subTree: true_ _#canvas_より下の任意のレベルにある場合。

docs から:

  • childList:ターゲットノードの子要素(テキストノードを含む)の追加と削除を監視する場合は、trueに設定します。
  • subtree:ターゲットとターゲットの子孫への変異が観察される場合は、trueに設定します。
7
acdcjunior