使用jQuery检测元素内容更改


113

change() 函数可以工作并检测表单元素的更改,但是有没有一种方法可以检测DOM元素的内容何时更改?

这是行不通的,除非#content是表单元素

$("#content").change( function(){
    // do something
});

我希望在执行类似操作时触发此操作:

$("#content").html('something');

另外html()append()函数没有回调。

有什么建议?


我知道一个老问题,但是请查看我的答案以寻求一个优雅的解决方案stackoverflow.com/a/23826615/744975
Andrew Atkinson 2014年

Answers:


26

这些是突变事件

我没有在jQuery中使用突变事件API,但是粗略的搜索使我进入了GitHub上的该项目。我不知道该项目的成熟度。


17
这个变体事件插件将不起作用,因为它只是将事件挂接到jQuery变体方法中。当jQuery本身尝试更改元素时会触发它们,但是当从jQuery外部更改元素时不会触发它们。他们不关注文档上的更改。看看这个小插件,而不是:stackoverflow.com/questions/3233991/jquery-watch-div/...
塞巴斯蒂安Grignoli

10
谷歌搜索并发布到您从未尝试过的库的链接并不是非常有用。(评论,因为我在
投票

27

突变事件的替代方法似乎是MutationObservers
WoodrowShigeru 2015年

69

我知道这篇文章已有1年的历史,但是我想为遇到类似问题的人提供不同的解决方案:

  1. jQuery change事件仅在用户输入字段上使用,因为如果有其他操作(例如div),则该操作来自代码。因此,找到操作发生的位置,然后在其中添加所需的任何内容。

  2. 但是,如果由于某种原因(您使用的是复杂的插件或找不到任何“回调”的可能性)而无法实现,那么我建议的jQuery方法是:

    一个。对于简单的DOM操作,请使用jQuery链接和遍历,$("#content").html('something').end().find(whatever)....

    b。如果您想做其他事情,请使用bind带有自定义事件的jQuery 和triggerHandler

    $("#content").html('something').triggerHandler('customAction');
    
    $('#content').unbind().bind('customAction', function(event, data) {
       //Custom-action
    });
    

这是jQuery触发器处理程序的链接:http : //api.jquery.com/triggerHandler/


1
最后的想法。尽管上面的内容应该很全面:您可以使用#content html值更新隐藏输入字段的值,然后将change事件绑定到隐藏输入字段:)很多选项
凯尔(Kyle)2010年

7
+1“找到操作发生的地方,然后在其中添加所需的任何内容。” 在2秒钟内解决了我的问题,没有任何hacks / plugins :)
Hartley Brody 2012年

我在这里建议的唯一更改是,bind期望您的处理程序返回bool
Serj Sagan 2015年

15

浏览器不会触发<div>元素的onchange事件。

我认为这背后的原因是,除非通过javascript进行修改,否则这些元素不会更改。如果您已经必须自己修改元素(而不是用户自己修改),则可以在修改元素的同时调用相应的随附代码,如下所示:

 $("#content").html('something').each(function() { });

您还可以手动触发这样的事件:

 $("#content").html('something').change();

如果这些解决方案都不适合您的情况,能否请您提供有关您要具体实现的目标的更多信息?


11
假设您已经编写了所有JavaScript,但事实并非如此。
Myster

谢谢!!!!这只是帮助我解决了我一直盯着6个小时的问题。
Jordan Parmer 2013年

正是我所需要的。
smac89 '17





3

从严格意义上讲,这不是jQuery的答案,但是对于调试来说却很有用。

在Firebug中,您可以右键单击DOM树中的元素,然后设置“属性更改中断”:

在Firebug中右键单击元素,并突出显示“更改属性时中断”

在脚本中更改属性后,将显示调试窗口,您可以跟踪其运行情况。下方还有一个用于元素插入和元素删除的选项(屏幕截图中的弹出窗口会掩盖这些内容)。


1
这很有帮助,但不完全是他的要求。这将检测类更改或添加或更改样式属性时的情况。它不会检查节点内部的内容何时更改。例如,如果某个地方的某些javascript将节点从<span> hello </ span>更改为<span> World </ span>,则无法检测到它
Joshua Soileau



1

通常,一种简单有效的方法是跟踪修改DOM的时间和地点。

您可以通过创建一个始终负责修改DOM的中央功能来做到这一点。然后,您可以从此函数中对修改后的元素进行所需的任何清理。

在最近的应用程序中,我不需要立即执行操作,因此我为方便的load()函数使用了回调,可以将类添加到任何已修改的元素中,然后每隔几秒钟使用setInterval计时器更新所有已修改的元素。

$($location).load("my URL", "", $location.addClass("dommodified"));

然后,您可以根据需要处理它-例如

setInterval("handlemodifiedstuff();", 3000); 
function handlemodifiedstuff()
{
    $(".dommodified").each(function(){/* Do stuff with $(this) */});
}

3
假设您已经编写了所有JavaScript,但事实并非如此。
Myster

1

您可以将回调选项添加到html(或任何)函数中:

$.fn.oldHtml = $.fn.html;
$.fn.html = function(html,fn){
  fn = fn || function(){};
  var result =  this.oldHtml(html);
  fn();
  return result;
};
$('body').html(11,function(){alert("haha");});

演示在这里。

您在某些元素上进行更改,而不是因必须捕获的内容而迫使元素进行更改。


我今天必须解决这个问题。我无法编辑实际上称为html()的代码,因为它位于第3方库中。修改后的版本对我来说很完美。我这样做:$ .fn.oldHtml = $ .fn.html(); $ .fn.html =函数(e){var结果= this.oldHtml(e); this.trigger('afterHtmlChange',e);}现在,我可以将所需的任何事件绑定到任何元素上的新创建的afterHtmlChange事件,该事件将在任何调用jQuery的html()fn时触发。
丹尼尔·霍华德

糟糕,轻微的错误。我上面的评论中的Fn应该是:function(e){var result = this.oldHtml(e); this.trigger('afterHtmlChange',e); 返回结果;}
丹尼尔·霍华德

0

我编写了一个片段,用于检查事件中元素的更改。

因此,如果您使用的是第三方JavaScript代码或其他内容,并且您需要知道单击后出现或更改的内容,则可以。

对于下面的代码段,假设您需要了解单击按钮后表格内容何时更改。

$('.button').live('click', function() {

            var tableHtml = $('#table > tbody').html();
            var timeout = window.setInterval(function(){

                if (tableHtml != $('#table > tbody').
                    console.log('no change');
                } else {
                    console.log('table changed!');
                    clearInterval(timeout);
                }

            }, 10);
        });

伪代码:

  • 一旦单击按钮
  • 捕获您希望更改的元素的html
  • 然后,我们不断检查元素的html
  • 当我们发现html不同时,我们将停止检查

0

我们可以通过使用Mutation Events来实现。根据www.w3.org所述,突变事件模块旨在允许通知文档结构的任何更改,包括属性和文本修改。欲了解更多详细的突变事件

例如 :

$("body").on('DOMSubtreeModified', "#content", function() {
    alert('Content Modified'); // do something
});

已经弃用了一段时间。一个人应该使用突变观察者(概念相同)
Carles Alcolea

-3

不可能,我相信发生了内容更改事件,但肯定不是x浏览器

我应该说如果没有一些讨厌的间隔在后台喘息的话是不可能的!


21
没有不可能的事!
jrharshath
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.