Виявити зміни вмісту елементів за допомогою jQuery


113

change() функція працює і виявляє зміни на елементах форми, але чи існує спосіб виявлення, коли змінено вміст елемента DOM?

Це не працює, якщо не #contentє елементом форми

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

Я хочу, щоб це спрацьовувало, роблячи щось на кшталт:

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

Крім того, html()чи append()функція не мають зворотної виклику.

Будь-які пропозиції?


я знаю старе запитання, але перевірте свою відповідь на елегантне рішення stackoverflow.com/a/23826615/744975
Ендрю Аткінсон,

Відповіді:


26

Це події мутації .

Я не використовував API подій мутації в jQuery, але побіжний пошук привів мене до цього проекту в GitHub. Я не знаю про зрілість проекту.


17
Цей плагін подій мутації не буде працювати, оскільки він просто підключає події до методів мутації jQuery. Вони запускаються, коли jQuery сам намагається змінити елементи, але не тоді, коли елементи змінюються ззовні jQuery. Вони не спостерігають за змінами в документі. Перевірте цей невеликий плагін замість: stackoverflow.com/questions/3233991/jquery-watch-div / ...
SEBASTIAN Grignoli

10
Гуглінг та публікація посилання на бібліотеку, яку ви ніколи не пробували, не дуже корисні. (Коментуючи, оскільки мене запропонували відхилити.)
Перестаньте наклепувати Моніку Челіо

27
Події мутації застаріли ; не використовуйте їх.
Брок Адамс

Альтернативою мутаційним подіям, здається, є MutationObservers .
WoodrowShigeru

69

Я знаю, що цій посаді рік, але я хотів би запропонувати інший підхід до вирішення питань, які мають подібне питання:

  1. Подія зміни jQuery використовується лише у полях введення користувача, оскільки якщо що-небудь інше маніпулюється (наприклад, div), ця маніпуляція походить від коду. Отже, знайдіть, де відбувається маніпуляція, а потім додайте туди все, що вам потрібно.

  2. Але якщо це неможливо з будь-якої причини (ви використовуєте складний плагін або не можете знайти жодних можливостей «зворотного виклику»), тоді я запропонував би підхід jQuery:

    а. Для простих маніпуляцій з DOM використовуйте ланцюги й обхід jQuery,$("#content").html('something').end().find(whatever)....

    б. Якщо ви хочете зайнятись чимось іншим, використовуйте jQuery's bindіз власною подією таtriggerHandler

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

Ось посилання на обробник тригерів jQuery: http://api.jquery.com/triggerHandler/


1
заключна думка. хоча це повинно бути досить вичерпним: ви можете оновити значення прихованого поля введення за допомогою HTML-коду #content, а потім прив’язати подію зміни до прихованого поля введення :) безліч варіантів
Кайл

7
+1 "Знайдіть, де відбувається маніпуляція, а потім додайте туди все, що вам потрібно." Виправлено мою проблему за 2 секунди без жодних злому / плагінів :)
Hartley Brody

Я пропоную лише зміни, що bindочікує, що ваш обробник поверне bool.
Serj Sagan

15

Веб-переглядач не запускає подію зміни на <div>елементи.

Я думаю, що аргументація цього полягає в тому, що ці елементи не змінюватимуться, якщо не будуть змінені JavaScript. Якщо вам вже доводиться самостійно змінювати елемент (а не користувач, який це робить), ви можете просто зателефонувати відповідному супроводжувальному коду одночасно, коли ви модифікуєте елемент, наприклад:

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

Ви також можете вручну запустити подію на зразок цієї:

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

Якщо жодне з цих рішень не підходить для вашої ситуації, ви можете, будь ласка, дати більше інформації про те, що ви конкретно намагаєтесь досягти?


11
Це передбачає, що ви написали весь javascript, що може бути не так.
Містер

СПАСИБІ!!!! Це просто допомогло мені вирішити проблему, на яку я дивився 6 годин.
Джордан Пармер

Саме те, що мені було потрібно.
smac89

15

як щодо http://jsbin.com/esepal/2

$(document).bind("DOMSubtreeModified",function(){
  console.log($('body').width() + ' x '+$('body').height());
})

Ця подія застаріла на користь API Mutation Observer


1
не погана ідея, хоча мені цікаво, яка підтримка у неї є. developer.mozilla.org/uk/DOM/DOM_event_reference/…
Elzo Valugi

Як ви відстежуєте конкретний елемент для змін? В даний час документ відстежує всю сторінку.
Патоші パ ト シ




3

Це не суто відповідь jQuery - але корисно згадати для налагодження.

У Firebug можна клацнути правою кнопкою миші елемент на дереві DOM та встановити "Перерва на зміну атрибутів":

Клацніть правою кнопкою миші елемент у Firebug із виділенням Перерва на зміну атрибутів

Коли атрибут змінено в сценарії, з'явиться вікно налагодження, і ви можете відстежити, що відбувається. Також є опція для вставки елементів та видалення елементів нижче (ненавмисне затемнення спливаючого вікна в екрані екрана).


1
Це корисно, але не саме те, про що він просив. Це виявить речі, наприклад, коли клас змінюється, або коли атрибут стилю додається чи змінюється. Він не перевірить, коли вміст із внутрішньої сторони вузла зміниться. Наприклад, якщо якийсь javascript десь змінить вузол з <span> привіт </span> на <span> Світ </span>, це не виявить
Джошуа Соало

2

Я розробляю крихітну бібліотеку JS під назвою mutabor ( https://github.com/eskat0n/mutabor ), яка спрямована на спрощення використання подій мутації DOM. Див. Demo.html для прикладів.



1

Часто простим та ефективним способом досягти цього є відстеження того, коли і де ви змінюєте DOM.

Це можна зробити, створивши одну центральну функцію, яка завжди відповідає за зміну DOM. Потім ви робите все необхідне очищення модифікованого елемента в межах цієї функції.

В останній програмі мені не потрібно було негайних дій, тому я використав зворотний виклик для функції зручного завантаження (), щоб додати клас до будь-яких модифікованих елементів, а потім оновлював усі змінені елементи кожні кілька секунд за допомогою таймера setInterval.

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

Тоді ви можете впоратися з нею як завгодно - наприклад

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

3
Це передбачає, що ви написали весь javascript, що може бути не так.
Містер

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 (), оскільки він знаходиться в сторонній бібліотеці. Змінена версія цього була для мене ідеальною. Я зробив це: $ .fn.oldHtml = $ .fn.html (); $ .fn.html = function (e) {var result = this.oldHtml (e); this.trigger ('afterHtmlChange', e);} Тепер я можу прив’язати будь-які потрібні події до новоствореної події afterHtmlChange на будь-якому елементі, який запускатиметься щоразу, коли що-небудь викликає html () fQ jQuery.
Даніель Говард

Упс, незначна помилка. Fn у моєму коментарі вище має бути: function (e) {var result = this.oldHtml (e); this.trigger ('afterHtmlChange', e); результат повернення;}
Даніель Говард

0

Я написав фрагмент, який перевірить на зміну елемента події.

Отже, якщо ви використовуєте код JavaScript 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

Ми можемо досягти цього, використовуючи мутаційні події . За даними www.w3.org, модуль події мутації розроблений, щоб дозволяти повідомляти про будь-які зміни в структурі документа, включаючи зміни attr та текст. Детальніше МУТАЦІЙНІ ПОДІЇ

Наприклад :

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

Це деякий час застаріло. Слід використовувати Спостерігачів мутацій (те саме поняття)
Карлес Алколія

-3

Неможливо, я вважаю, що є подія, змінена змістом, але це, звичайно, не x-браузер

Чи варто сказати, що це неможливо без якогось неприємного інтервалу, відбиваючись на задньому плані!


21
Немає нічого неможливого!
jrharshath
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.