我有一个简单的MutationObserver
设置作为测试。 HTML有一个span
,其文本内容每秒更新一次(邮件的div
更新):
<span class="tester"></span>
<div id="msg"></div>
MutationObserver设置为观看.tester
,并在观察到更改时将文字写入#msg
div
。同时,setInterval()
运行一次/秒以更改.tester
中的文字:
var target = document.querySelector('.tester');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
$('#msg').append(mutation.type+"<br/>")
setTimeout(function() { $('#msg').text(''); }, 500);
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
setInterval(function() {
$('#msg').text('');
$('.tester').text("update: "+Math.random())
}, 1000);
我希望此代码每秒打印一次 characterData 已更改。根据{{3}},它描述了characterData:&#34;如果要观察到目标数据的突变,则设置为true。&#34;相反,我看不到characterData突变,但 do 每秒都会看到两个childList突变。
为什么我没有看到任何characterData突变,为什么我看到两个 childList突变?
以下是Mozilla's docs for MutationObserver的工作示例。
答案 0 :(得分:6)
原因是Jeremy Banks said:当您使用jQuery&#39; text()
时,它会删除所有文本节点,然后添加新节点。这不是对字符数据的更改,而是childList
的更改:删除那里的节点并将其替换为新节点。
要查看对字符数据的更改,您必须修改现有文本节点nodeValue
,和观察subtree
修改:
var target = document.querySelector('.tester');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
snippet.log(mutation.type);
$('#msg').append(mutation.type+"<br/>")
setTimeout(function() { $('#msg').text(''); }, 500);
});
});
var config = {
attributes: true,
childList: true,
characterData: true,
subtree: true // <=== Change, added subtree
};
observer.observe(target, config);
var timer = setInterval(function() {
$('#msg').text('');
// Change --VVVVV modifying the existing child node
$('.tester')[0].firstChild.nodeValue = "updated" + Math.random();
}, 1000);
// Stop after 10 seconds
setTimeout(function() {
clearInterval(timer);
}, 10000);
&#13;
<span class="tester">x</span><!-- Change, added a starting child node -->
<div id="msg"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
回答你关于为什么会有两个 childList
突变的问题,是的,我认为你是对的:他们正在删除孩子,然后添加一个新孩子。如果我们使用replaceChild
method,我们只能看到一个突变:
var target = document.querySelector('.tester');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
snippet.log(mutation.type);
$('#msg').append(mutation.type+"<br/>")
setTimeout(function() { $('#msg').text(''); }, 500);
});
});
var config = {
attributes: true,
childList: true,
characterData: true,
subtree: true // <=== Change, added subtree
};
observer.observe(target, config);
var timer = setInterval(function() {
$('#msg').text('');
// Change --VVVVV modifying the existing child node
var text = document.createTextNode("updated" + Math.random());
var parent = $('.tester')[0];
parent.replaceChild(text, parent.firstChild);
}, 1000);
// Stop after 10 seconds
setTimeout(function() {
clearInterval(timer);
}, 10000);
&#13;
<span class="tester">x</span><!-- Change, added a starting child node -->
<div id="msg"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;