jQuery事件:检测对div的html/text的更改

我有一个div,它的内容一直在变化,是ajax requestsjquery functionsblur等。

是否有一种方法可以在任何时间点检测我的div上的任何变化?

我不想使用任何间隔或默认值检查。

这样就可以了

$('mydiv').contentchanged() {
alert('changed')
}
585382 次浏览

你正在寻找MutationObserver突变事件。它们既没有得到任何地方的支持,也没有被开发人员世界过于钟爱。

如果你知道(并能确保)div的大小会改变,你可以使用跨浏览器调整大小事件

添加一些内容到div,无论是通过jQuery还是直接通过de DOM-API,默认为.appendChild()函数。你能做的是覆盖当前对象的.appendChild()函数,并在其中实现一个观察者。现在已经重写了.appendChild()函数,我们需要从另一个对象中借用该函数,以便能够追加内容。因此,我们调用另一个div的.appendChild()来最后追加内容。当然,这也适用于.removeChild()

var obj = document.getElementById("mydiv");
obj.appendChild = function(node) {
alert("changed!");


// call the .appendChild() function of some other div
// and pass the current (this) to let the function affect it.
document.createElement("div").appendChild.call(this, node);
}
};

这里你可以找到一个naïf的例子。我想你们可以自己扩展。 http://jsfiddle.net/RKLmA/31/ < / p >

顺便说一下:这表明JavaScript遵循openclose原则。:)

您可以将div的旧innerHTML存储在一个变量中。设置检查旧内容与当前内容是否匹配的时间间隔。如果这不是真的,那就做点什么。

如果你不想使用定时器和检查innerHTML,你可以尝试这个事件

$('mydiv').on('DOMSubtreeModified', function(){
console.log('changed');
});

更多细节和浏览器支持数据是在这里

你可以试试这个

$('.myDiv').bind('DOMNodeInserted DOMNodeRemoved', function() {


});

但这在ie浏览器中可能行不通,我还没测试过

这个问题没有内在的解决方案,这是你的设计和编码模式的问题。

您可以使用发布者/订阅者模式。为此,您可以使用jQuery自定义事件或自己的事件机制。

首先,

function changeHtml(selector, html) {
var elem = $(selector);
jQuery.event.trigger('htmlchanging', { elements: elem, content: { current: elem.html(), pending: html} });
elem.html(html);
jQuery.event.trigger('htmlchanged', { elements: elem, content: html });
}

现在你可以订阅divhtmlchanging/divhtmlchanged事件,如下所示,

$(document).bind('htmlchanging', function (e, data) {
//your before changing html, logic goes here
});


$(document).bind('htmlchanged', function (e, data) {
//your after changed html, logic goes here
});

现在,你必须通过changeHtml()函数来改变你的div内容。因此,你可以监视或相应地做必要的更改,因为绑定回调数据参数包含信息。

你必须像这样更改div的html;

changeHtml('#mydiv', '<p>test content</p>');

而且,除了input元素,你可以将它用于任何html元素。无论如何,您可以修改它以用于任何元素。

试试MutationObserver:

浏览器支持:http://caniuse.com/#feat=mutationobserver

<html>
<!-- example from Microsoft https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/dev-guide/dom/mutation-observers/ -->


<head>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
// Inspect the array of MutationRecord objects to identify the nature of the change
function mutationObjectCallback(mutationRecordsList) {
console.log("mutationObjectCallback invoked.");


mutationRecordsList.forEach(function(mutationRecord) {
console.log("Type of mutation: " + mutationRecord.type);
if ("attributes" === mutationRecord.type) {
console.log("Old attribute value: " + mutationRecord.oldValue);
}
});
}
      

// Create an observer object and assign a callback function
var observerObject = new MutationObserver(mutationObjectCallback);


// the target to watch, this could be #yourUniqueDiv
// we use the body to watch for changes
var targetObject = document.body;
      

// Register the target node to observe and specify which DOM changes to watch
      

      

observerObject.observe(targetObject, {
attributes: true,
attributeFilter: ["id", "dir"],
attributeOldValue: true,
childList: true
});


// This will invoke the mutationObjectCallback function (but only after all script in this
// scope has run). For now, it simply queues a MutationRecord object with the change information
targetObject.appendChild(document.createElement('div'));


// Now a second MutationRecord object will be added, this time for an attribute change
targetObject.dir = 'rtl';




</script>
</body>
</html>

因为$("#selector").bind()已弃用,你应该使用:

$("body").on('DOMSubtreeModified', "#selector", function() {
// code here
});

使用Javascript MutationObserver:

// Select the target node.
var target = document.querySelector('mydiv')


// Create an observer instance.
var observer = new MutationObserver(function(mutations) {
console.log(target.innerText);
});


// Pass in the target node, as well as the observer options.
observer.observe(target, {
attributes:    true,
childList:     true,
characterData: true
});

详情请参阅MDN文档;这应该工作在几乎所有当前的浏览器,包括IE11。

下面的代码为我工作:

$("body").on('DOMSubtreeModified', "mydiv", function() {
alert('changed');
});

使用MutationObserver,如Mozilla提供的代码片段所示,并改编自这篇博文

或者,你可以使用JQuery的例子见此链接

Chrome 18+, Firefox 14+, IE 11+, Safari 6+

// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');


// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };


// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type == 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};


// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);


// Start observing the target node for configured mutations
observer.observe(targetNode, config);


// Later, you can stop observing
observer.disconnect();

尝试了上面给出的一些答案,但这些火灾发生了两次。如果你需要的话,这里有一个工作解决方案。

$('mydiv').one('DOMSubtreeModified', function(){
console.log('changed');
});

DOMSubtreeModified不是一个好的解决方案。如果你决定在事件处理程序中更改DOM,它可能会导致< >强无限循环< / >强,因此它在许多浏览器中已被禁用。MutationObserver是更好的答案。

MDN Doc

const onChangeElement = (qSelector, cb)=>{
const targetNode = document.querySelector(qSelector);
if(targetNode){
const config = { attributes: true, childList: false, subtree: false };
const callback = function(mutationsList, observer) {
cb($(qSelector))
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
}else {
console.error("onChangeElement: Invalid Selector")
}
}

你可以这样使用它,

onChangeElement('mydiv', function(jqueryElement){
alert('changed')
})