我有一个div,它的内容始终在变化,例如ajax requestsjquery functionsblur等。 br />
我不想使用任何间隔或检查的默认值。

类似的事情会做

评论

可能重复:stackoverflow.com/questions/10328102/…

@Rob将keypress事件绑定到contenteditable
元素。我不确定那里的解决方案是否适用于此。他们绝对不会对元素的内容进行任何程序更改。

#1 楼

如果您不想使用计时器并检查innerHTML,则可以尝试此事件

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


更多详细信息和浏览器支持数据在这里。

注意:在较新的jQuery版本中,不建议使用bind(),因此应改用on():

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


评论


请记住,IE8(及以下版本)不支持DOMSubtreeModified。

–加文
13年8月15日在18:21

不推荐使用此事件w3.org/TR/DOM-Level-3-Events/#glossary-deprecated

– Isaiyavan Babu Karan
2014年5月5日在9:06

Mozilla 33:归因于元素的递归。需要寻找另一种方法

–Chaki_Black
2014-10-28 17:32



严重的是,请勿使用此事件,因为它会导致您的所有工作崩溃,并且始终被触发。而是使用$('。myDiv')。bind('DOMNodeInserted DOMNodeRemoved',function(){});下的事件。

–乔治SEDRA
16 Mar 3 '16 at 14:48

此方法已被弃用!而是使用:$(“ body”)。on('DOMSubtreeModified',“ mydiv”,function(){});

– Asif
16 Jun 7'在6:28



#2 楼

使用Javascript MutationObserver

  //More Details https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
 // select the target node
var target = document.querySelector('mydiv')
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  console.log($('mydiv').text());   
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);


评论


这是正确的答案,因为现在比使用DOMSubtreeModified更受青睐

–乔尔·戴维(Joel Davey)
18-10-11在11:56

即使我给出了正确的选择器,我也对此出错。 “ VM21504:819未捕获的TypeError:无法在'MutationObserver'上执行'观察':参数1的类型不是'节点'。”

–samir
19年7月18日在9:38



@samir当找不到您选择的元素时,错误发生。代码执行时,您尝试观察的元素可能不存在。这个答案很有用

–朋友
9月28日15:42



我将在此片段。 HTMLElement.prototype.onDOMSubtreeModified = function(c,o = {属性:true,childList:true,characterData:true}){返回新的MutationObserver((m)=> {c.call(this,m);})。观察(this,o);};

–GramThanos
11月20日15:35

#3 楼

由于不赞成使用$("#selector").bind(),因此您应该使用:

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


评论


这是区分因素,附加的#表示符号必须在选择器之前。

–克里斯-小
17年11月2日在22:36

它确实有效。#indiv的Changin #selector做到了,谢谢

–路易斯·H·卡布雷霍
9月7日下午3:13

#4 楼

您可以尝试一下

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

});


,但这可能无法在Internet Explorer中使用,尚未对其进行测试

评论


代理:developer.mozilla.org/en-US/docs/Web/Guide/Events/…改用:developer.mozilla.org/en-US/docs/Web/API/MutationObserver

–兰德尔·弗拉格(Randall Flagg)
2015年10月15日在9:38

注意!:如果将它用作触发器,并且对该页面进行了很多更改,它将使您的函数运行X次(甚至X = 1,000或更多),这可能会非常低效。一个简单的解决方案是定义一个“正在运行的”布尔值var,它将... if(running == true){return} ...如果已经在运行代码,则无需运行。在if逻辑之后立即设置running = true,在函数退出之前将running = false设置。您还可以使用计时器将功能限制为只能每X秒运行一次。 running = true; setTimeout(function(){running = false},5000); (或更好的东西)

– JxAxMxIxN
16年8月21日在16:43



我在一个具有添加和删除选项的选择框上使用了此功能。添加项目时效果很好,但删除似乎落后了1个项目。删除最后一个选项后,它将不会触发。

– CodeMonkey
17 Mar 5 '17 at 7:37

@JxAxMxIxN您也可以通过再次清除并设置超时来增加超时计时器:clearTimeout(window.something); window.something = setTimeout(...);

– Ctrl-C
17年5月23日在11:17

同意-您的路是要走的路-自从学习Python以来,我已经清除了我使用多种语言编写的许多不良编码实践(不是全部,只是很多;)

– JxAxMxIxN
17年5月24日在1:38

#5 楼

您正在寻找MutationObserver或Mutation Events。不论是在任何地方都不受支持,也不是开发人员对它的关注程度过高。

评论


这是一个。具体来说,是DOMSubtreeModified。您可能会发现突变摘要库很有用,并且此DOM树事件列表也是如此。

–BenjaminRH
13年5月24日在9:32

不推荐使用此事件developer.mozilla.org/zh-CN/docs/Web/Guide/Events/…

– Adrien Be
14年7月30日在11:58

万一其他人不得不尝试通读所有地方的所有内容,这是正确的答案。过去的浏览器支持突变事件,而现代浏览器将支持突变观察者,将来也将支持。请参阅支持链接:CANIUSE突变观察者

–乔什·麦克(Josh Mc)
16 Mar 9 '16 at 21:25

#6 楼

以下代码对我有用。

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


希望对别人有帮助:)

评论


这是与@Artley的回答相同的答案

–黑色
18年1月13日在13:23

@黑色谢谢!我刚刚检查了Artley的答案。下次我会照顾的。

– Sanchit Gupta
18年1月14日在13:46

#7 楼

没有内置解决方案可以解决此问题,这是您的设计和编码模式中的问题。

您可以使用发布者/订阅者模式。为此,您可以使用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函数修改为使用'elem.trigger(...)'而不是'jQuery.event.trigger(...)',然后像这样绑定到元素$('#my_element_id')。on('htmlchanged',function(e,data){...}

– KenB
2014年8月1日在17:14

“这是您的设计和编码模式的问题”,如果包含第三方脚本,那么您将无法控制其源代码,该怎么办?但是您需要检测它们对一个div的更改?

– DrLightman
16 Sep 19'在12:53

@DrLightman的经验法则是选择提供回调事件的第三方库

– Marcel Djaman
17年11月30日在15:01

#8 楼

使用Mozilla提供的此代码段中的MutationObserver,并改编自此博客文章

或者,您可以使用此链接中的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();


#9 楼

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

#10 楼

尝试MutationObserver:


https://developer.microsoft.com/zh-CN/microsoft-edge/platform/documentation/dev-guide/dom/mutation-observers/

https://developer.mozilla.org/zh-CN/docs/Web/API/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> 




#11 楼

尝试了上面给出的一些答案,但是两次触发事件。如果您需要相同的解决方案,请使用以下方法。
$('mydiv').one('DOMSubtreeModified', function(){
    console.log('changed');
});


#12 楼

无论是通过jQuery还是直接通过DOM-API,向div中添加一些内容都默认为.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);
        }
    };

在这里您可以找到一个简单的示例。我猜您可以自己扩展它。
http://jsfiddle.net/RKLmA/31/
顺便说一句:这表明JavaScript符合OpenClosed原理。 :)

评论


它不适用于追加子项...实际上我通过其他功能修改了它的html。

– BoqBoq
13 Mar 27 '13 at 12:32

像removeChild()replaceChild()等。但是您使用的是innerHTML。您应该以某种方式避免它。

– Andries
13年3月27日在12:39

#13 楼

DOMSubtreeModified不是一个好的解决方案。如果您决定更改事件处理程序内部的DOM,则可能导致无限循环,因此已在许多浏览器中将其禁用。 MutationObserver将是答案。
MDN文档
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')
})