Мне нужен новый способ определить, было ли изменение элементов HTML

Теперь я пытаюсь найти способ обнаружить, когда изменился элемент HTML.

В настоящее время я пытаюсь:

var a, b;
setInterval(function() {
    a = $('#chat').text();
}, 150);
setInterval(function() {
    b = $('#chat').text();
    if (a !== b) {
        alert("There has been a new message.");
    }
}, 200);​

То, что я делаю, каждые 150 миллисекунд, я проверяю на HTML #chat, а затем каждые 200 секунд снова проверяю HTML, а затем проверяю, не изменит ли переменная a переменная b в будущем. так что-то с этим, но сейчас я просто что-то предупреждаю.

Здесь вы можете увидеть его здесь: http://jsfiddle.net/MT47W/

Очевидно, что этот способ не работает и не очень точен. Есть ли лучшее/отличное решение для этого?

Спасибо за любую помощь, я пытался выяснить, как сделать это лучше уже около недели, но я просто не могу найти решение для этого, и я надеюсь, что я разместил эту проблему справа место и в нужное время.

Ответ 1

Используйте var для хранения текущего элемента text, затем проверьте его в setInverval и обновите var, чтобы сохранить текущий text после проверки:

var a = $('#chat').text();
setInterval(function() {
    if (a !== $('#chat').text()) { //checks the stored text against the current
        alert("There has been a new message."); //do your stuff
    }
    a = $('#chat').text(); //updates the global var to store the current text
}, 150); //define your interval time, every 0.15 seconds in this case

Fiddle

Вы также можете сохранить значение в .data() этого элемента, чтобы избежать использования глобальных символов.

Пример использования .data():

$('#chat').data('curr_text', $('#chat').text());
setInterval(function() {
    if ($('#chat').data('curr_text') !== $('#chat').text()) {
        alert("There has been a new message.");
    }
     $('#chat').data('curr_text', $('#chat').text());
}, 150);

Fiddle

Другой подход, чтобы сохранить клиентскую память, вы можете просто сохранить количество дочерних элементов div для вашего элемента #chat:

$('#chat').data('n_msgs', $('#chat').children().length);
setInterval(function() {
    if ($('#chat').data('n_msgs') !== $('#chat').children().length) {
        alert("There has been a new message.");
    }
     $('#chat').data('n_msgs', $('#chat').children().length);
}, 150);

Fiddle


EDIT: Здесь мое последнее дополнение, с прослушиванием событий мутации DOM:
$('#chat').on('DOMNodeInserted', function() {
    alert("There has been a new message.");
});

Fiddle (не тестировался в IE < 8)

Примечание.. Как отмечено в комментариях, несмотря на то, что события мутации все еще поддерживаются, они классифицируются как устаревшие от W3C из-за потери производительности и некоторых несовместимостей в разных браузерах, поэтому он предложил использовать одно из вышеперечисленных решений и использовать только события DOM Mutation, когда нет другого пути.

Ответ 2

Просто проверка последнего чата повысит эффективность, а также сделает то, что вы хотите. Единственный способ, что он не сработает, - это тот же самый человек, который дважды отправляет одно и то же сообщение, что, скорее всего, не произойдет.

Я надеюсь, что это сработает:

 var lastMessage = $('#chat .body').last().text();
    function checkMessages(){
        var newLastMessage = $('#chat .body').last().text();
        if(lastMessage !== newLastMessage && $('#chat .body').last().length > 0){
             //message has changed
            alert("There has been a new message.");
            lastMessage = $('#chat .body').last().text();
        }
        setTimeout(function(){checkMessages();},1000);
    }
    checkMessages();

Js Fiddle

Ответ 3

Используйте хеширование crc32 или md5, чтобы проверить, изменились ли данные. Просто получите содержимое html в div, которое вы хотите проверить, хешируйте его как строку с crc32 или md5, и вы получите строку, которая будет представлять это содержимое. Используйте скрытую метку времени и т.д., Чтобы убедиться, что несколько сообщений одного пользователя получают другой хеш. Если вы сделаете это в обратном вызове setInterval, вы должны быть хорошими.

Ответ 4

Хотя он не рекомендуется, также можно использовать метод Paul Irish Duck punching, чтобы связать Функция jQuery append - если вы точно знаете, что функция append заключается в том, как добавляется контент (demo):

(function($) {
    // store original reference to the method
    var _old = $.fn.append;
    $.fn.append = function(arg) {
        // append as usual
        _old.apply(this, arguments);

        // do your own checking here
        // "this" is a jQuery object
        if (this[0].id === "chat") {
            alert('there is a new message!');
        }
        return this;
    };

})(jQuery);

С помощью этого метода не требуются циклы синхронизации.