jQuery - 在DOM更改时运行一个函数

时间:2011-01-22 02:23:47

标签: javascript ajax jquery

到目前为止,我一直在使用livequery,但这会使页面浏览看起来很慢。 所以我正试图为此寻找替代解决方案。

我附加了一个函数,该函数在具有某个类的元素上运行一些ajax,如:

$(".blah").each(function(){
  $.ajax({
      ...
      success: function(data) { 
        $(this).removeClass(".blah");
        // do other stuff
      }
  });
});

现在我有几个事件挂钩在可以在DOM中附加html的不同元素,例如:

$(".button").click(function(){
  $.ajax({
      ...
      success: function(data) { 
        $(this).append(data);
        // here, new elements with ".blah" class could be inserted in the DOM
        // the event above won't be fired...
      }
  });
});

如果在其他事件中更新DOM,我怎么能这样运行上面的第一个ajax函数?

更新

我也找到了这个插件: http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/

你认为这是一个更好的解决方案吗?从快速查看看起来,因为它允许您设置“轮询”间隔,如果将其设置为1秒或某些时间,可能会降低CPU使用率。我现在正在测试它:)

更新2:

不幸的是,它仅适用于元素ID,原因有些奇怪:(

4 个答案:

答案 0 :(得分:13)

大多数主流浏览器(但遗憾的是不是IE< = 8)支持DOM mutation events(另见MDN)。如果您只想将节点添加到DOM中,请使用DOMNodeInserted事件。如果您想了解任何DOM更改,请使用catch-all DOMSubtreeModified事件。

例如:

document.addEventListener("DOMNodeInserted", function(evt) {
    alert("Node inserted. Parent of inserted node: " + evt.relatedNode.nodeName);
}, false);

document.body.appendChild( document.createElement("div") );

2012年12月13日更新

现在不推荐使用DOM突变事件,浏览器逐渐转移到mutation observers。目前最明智的策略似乎是使用变异观察者并回归突变事件。

答案 1 :(得分:2)

这是真的,因为新元素没有绑定到回调的事件,它们只是新的元素。我建议在新创建的元素创建之后(即在ajax成功函数内)绑定事件:

    $(".blah").each(function(){
      $.ajax({
          ...
          success: function(data) { 
            $(this).removeClass(".blah");
            // add handlers to new elements with class "button"
            $(this).find('.button').click(function() {  
                     $.ajax({
                          success: function(data) { 
                            $(this).append(data);
                          });
          }
      });
    }

答案 2 :(得分:1)

我也遇到过这样的问题。没有真正的方法让dom改变(我知道)。我通过两种不同的方法来解决这个问题

  1. 让setTimeout每秒调用一次该函数,或者在用户移动鼠标时触发该函数。如果处理不当,这两种情况都会造成缓慢下降
  2. 在ajax完成时调用一个函数。因此,每次通过在成功部分中完成查询来调用doAjax()。
  3. 你也可以将第一个ajax查询绑定到body标签,这样当用户点击ajax事件时会触发的任何内容,然后检查是否符合正确的标准。

    编辑:这可能有效。添加$(“BODY ID / CLASS”)。change(function(){});不完全确定,因为我不是最流利的jQuery。

答案 3 :(得分:1)

IE9 +,FF和Chrome:

var observeDOM = (function(){
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
        eventListenerSupported = window.addEventListener;

    return function(obj, callback){
        if( MutationObserver ){
            // define a new observer
            var obs = new MutationObserver(function(mutations, observer){
                if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
                    callback();
            });
            // have the observer observe foo for changes in children
            obs.observe( obj, { childList:true, subtree:true });
        }
        else if( eventListenerSupported ){
            obj.addEventListener('DOMNodeInserted', callback, false);
            obj.addEventListener('DOMNodeRemoved', callback, false);
        }
    }
})();

observeDOM( $('#dom_element')[0] ,function(){ 
    console.log('dom changed');
});