我有以下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的变化......
答案 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>