jQuery - запустить функцию при изменении DOM - PullRequest
5 голосов
/ 22 января 2011

Я до сих пор использовал livequery , который работает, но это делает просмотр страниц действительно медленным.Поэтому я пытаюсь найти альтернативное решение для этого.

Я прилагаю функцию, которая запускает некоторый ajax для элементов с определенным классом, например:

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

Теперь у меня естьнесколько событий подключены к различным элементам, которые могут добавлять html в DOM, например:

$(".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...
      }
  });
});

Как я могу сделать так, чтобы первая вышеупомянутая функция ajax запускалась, когда DOM обновляется в других событиях?1012 * Обновление:

Я также нашел этот плагин: http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/

Как вы думаете, это будет лучшее решение?На первый взгляд кажется, что это позволяет вам установить интервал опроса, который может уменьшить использование процессора, если вы установите его на 1 сек или что-то в этом роде.Я сейчас тестирую:)

Обновление 2:

К сожалению, он работает только с идентификаторами элементов по какой-то странной причине: (*

Ответы [ 4 ]

13 голосов
/ 22 января 2011

Большинство основных браузеров (но, к сожалению, не IE <= 8) поддерживают <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents" rel="nofollow noreferrer"> события мутации DOM (также см. 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") );

Обновление 13 декабря 2012

DOMсобытия мутации теперь устарели, и браузеры постепенно переходят к наблюдателям мутаций .Кажется, что наиболее разумной стратегией на данный момент является использование наблюдателей мутаций и возврат к мутационным событиям.

2 голосов
/ 22 января 2011

Это правда, потому что новые элементы не имеют событий, связанных с обратными вызовами, они просто новые свежие элементы. Я бы порекомендовал связывать события с вновь созданными элементами сразу после их создания (то есть внутри функции успеха 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);
                          });
          }
      });
    }
1 голос
/ 29 января 2013

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');
});
1 голос
/ 22 января 2011

Я тоже столкнулся с такой проблемой.Не существует верного способа заставить что-то измениться из-за перемен (о которых я знаю).Я подошел к этому с помощью двух разных методов

  1. У setTimeout вызывается функция каждую секунду или функция запускается, когда пользователь перемещает мышь.Оба из них могут вызвать замедление, если не обработаны правильноТак что просто вызывайте doAjax () каждый раз, когда вы завершаете запрос, помещая его в раздел успеха.

Вы также можете иметь первый ajax-запрос, связанный с тегом body, поэтому каждый раз, когда пользователь нажимает на что-то, что сработает событие ajax, а затем проверяет, удовлетворены ли нужные критерии.

Изменить: это может работать.Добавьте $ ("BODY ID / CLASS"). Change (function () {});Не совсем уверен, так как я не самый беглый в jQuery.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...