DOM Mutation Observer用于更改事件的Callback和Child类

时间:2016-04-14 17:47:43

标签: javascript jquery

我有以下DOM Mutation Observer代码:

<script type="text/javascript">
var targetNodes         = $("#history");
var MutationObserver    = window.MutationObserver || window.WebKitMutationObserver;
var myObserver          = new MutationObserver (mutationHandler);
var obsConfig           = { childList: true, characterData: true, attributes: true, subtree: true };
//--- Add a target node to the observer. Can only add one node at a time.
targetNodes.each ( function () {
    myObserver.observe (this, obsConfig);
} );
function mutationHandler (mutationRecords) {
    console.info ("mutationHandler:");

    mutationRecords.forEach ( function (mutation) {
        $("span.badge").show();      
    } );
}
</script>

在#history id中检测到事件更改时,它正常工作。

<p id="history"></p>

问题是我在#history中有一些p.class如下:

<p id="history">
 <p class="mine"></p>
 <p class="theirs"></p>
 </p>

我只需要在p class =“他们的”中检测观察者的变化。

这怎么可能只用于子类,而不是在整个#history id中观察DOM的变化......

1 个答案:

答案 0 :(得分:2)

<强>简介

使用格式时:

$("#history").each ( function () {
        myObserver.observe (this, obsConfig);
    });
这没用。 $(“#history”)返回一个元素或什么都不返回。 要测试是否返回值,您可以使用

$("#history").length

在您的情况下,此值为1.请记住,不能存在多个具有相同ID的元素(请参阅:#selector)。

在每个循环中使用this关键字。此关键字的值是observe函数所需的“节点目标”元素。

所以,因为你只有一个历史元素,所以只循环一个元素是完全没用的(参考:每个函数)。单独使用该值。

也可以使用以下方法搜索此值:

var  target = document.getElementsByClassName('theirs')[0];

target = document.querySelectorAll('.theirs')[0];

target = $('.theirs').get(0);

当然,如果你没有这样的新元素可以观察到你不能使用观察功能。

有关详细信息,请参阅MutationObserver

最好的方法是测试所选元素的返回值,例如:

       if ($('.theirs').length == 0) {
            // raise error and stop
        } else {
            target = $('.theirs').get(0);
        }

相反,如果您有多个元素,则可以继续使用每个循环:

    $(".theirs").each ( function () {
        myObserver.observe (this, obsConfig);
    });

我的建议:

根据HTML Paragraph tag,您不能使用嵌套段落。

如果您只需要观察“他们的”段落会发生什么,您只需要更改一下代码:

$(function () {
  var targetNodes = $(".theirs");
  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  var myObserver = new MutationObserver(mutationHandler);
  var obsConfig = {childList: true, characterData: true, attributes: true, subtree: true};

  // get the target node on which to observe DOM mutations
  var  target = document.getElementsByClassName('theirs')[0];

  // another way to get the target is
  target = document.querySelectorAll('.theirs')[0];

  // another way to get the target is
  if ($('.theirs').length == 0) {
    // raise error and stop
  } else {
    target = $('.theirs').get(0);
  }

  myObserver.observe(target, obsConfig);
  function mutationHandler(mutationRecords) {
    alert("mutationHandler:");

    mutationRecords.forEach(function (mutation) {
      $("span.badge").show();
    });
  }

  $('#btn').on('click', function (e) {
    $('.theirs').text('Date Now is: ' + Date.now());
  });
});
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>

<div id="history">
   <p class="mine"></p>
   <p class="theirs"></p>
</div>

<button id="btn">Add text to theirs</button>

如果您对仅在div中添加或更改过的段落发生更改感兴趣,请根据以下MutationRecord我仅报告如何过滤新添加的节点的事件的演示(记得开始和停止观察者):

var myObserver = null;

function mutationHandler(mutationRecords, mutationInstance) {
  // new node added
  if (mutationRecords.length == 1 && mutationRecords[0].addedNodes.length == 1) {
    // if element added is a paragraph with class theirs....
    var eleAdded = $(mutationRecords[0].addedNodes[0]);
    if (eleAdded.is('p.theirs')) {
      alert("mutationHandler: added new paragraph with class theirs: " + eleAdded.text());
    }
  }
  // if you need to listen for other events like attribute changed or element removed... please read the documentation regarding mutationRecords object
}

$(function () {
  $('#startObserver').on('click', function(e) {
    var targetNodes = $('#history');
    var target = null;
    if (targetNodes.length != 1) {
      alert('Cannot start Observer on no element!')
      return;
    } else {
      target = targetNodes.get(0);
    }
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
    myObserver = new MutationObserver(mutationHandler);
    var obsConfig = {childList: true, characterData: true, attributes: true, subtree: true};

    myObserver.observe(target, obsConfig);
  });

  $('#stopObserver').on('click', function(e) {
    if (myObserver === null) {
      alert('Cannot stop an Observer never started!')
    } else {
      myObserver.disconnect();
      myObserver = null;
    }
  });

  $('#btnMine').on('click', function (e) {
    var txt = $('#mineInput').val();
    $('#history').prepend('<p class="mine">Added mine paragraph with text: ' + (txt.trim() ? txt : 'empty text!') + '</p>');
  });

  $('#btnTheirs').on('click', function (e) {
    var txt = $('#theirsInput').val();
    $('#history').append($('<p class="theirs">Added theirs paragraph with text: ' + (txt.trim() ? txt : 'empty text!') + '</p>'));
  });
});
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>

<div id="history">
</div>

Mine paragraphs text: <input id="mineInput" type="text"><br>
Theirs paragraphs text: <input id="theirsInput" type="text"><br>
<button id="btnMine">Add new Mine paragrapgh</button>
<button id="btnTheirs">Add new Theirs paragrapgh</button><br><br>
<button id="startObserver">Start Observer</button>
<button id="stopObserver">Stop Observer</button>