JQuery ile öğe içeriği değişikliklerini tespit edin


113

change() işlevi çalışır ve form öğelerindeki değişiklikleri algılar, ancak bir DOM öğesinin içeriğinin ne zaman değiştirildiğini algılamanın bir yolu var mı?

Bu #content, bir form öğesi olmadığı sürece çalışmaz

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

Bunun aşağıdaki gibi bir şey yaparken tetiklenmesini istiyorum:

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

Ayrıca html()veya append()işlevin bir geri araması yoktur.

Baska öneri?


eski soru biliyorum ama şık bir çözüm için cevabımı kontrol et stackoverflow.com/a/23826615/744975
Andrew Atkinson

Yanıtlar:


26

Bunlar mutasyon olaylarıdır .

JQuery'de mutasyon olay API'leri kullanmadım, ancak üstünkörü bir arama beni GitHub'daki bu projeye yönlendirdi . Projenin olgunluğunun farkında değilim.


17
Bu mutasyon olayları eklentisi çalışmaz çünkü olayları jQuery mutasyon yöntemlerine bağlar. JQuery'nin kendisi öğeleri değiştirmeye çalıştığında, ancak öğeler jQuery'nin dışından değiştirildiğinde ateşlenirler. Belgedeki değişiklikleri izlemezler. Bunun yerine şu küçük eklentiye göz atın: stackoverflow.com/questions/3233991/jquery-watch-div/…
Sebastián Grignoli

10
Googling yapmak ve hiç denemediğiniz bir kitaplığa bağlantı göndermek o kadar da yararlı değildir. (Yorum yapıyorum çünkü olumsuz oylamam istendi.)
Monica


Mutasyon olaylarına alternatif, MutationObservers gibi görünüyor .
WoodrowShigeru

69

Bu yazının bir yaşında olduğunu biliyorum ama benzer sorunu olanlara farklı bir çözüm yaklaşımı sunmak istiyorum:

  1. JQuery değişiklik olayı yalnızca kullanıcı girdi alanlarında kullanılır, çünkü başka bir şey değiştirilirse (örneğin, bir div), bu işlem koddan gelir. Yani, manipülasyonun nerede gerçekleştiğini bulun ve ardından ihtiyacınız olanı oraya ekleyin.

  2. Ancak herhangi bir nedenle bu mümkün değilse (karmaşık bir eklenti kullanıyorsanız veya herhangi bir "geri arama" olasılığı bulamıyorsanız), önereceğim jQuery yaklaşımı şudur:

    a. Basit DOM manipülasyonu için jQuery zincirleme ve çapraz geçişi kullanın,$("#content").html('something').end().find(whatever)....

    b. Başka bir şey yapmak isterseniz, jQuery'leri bindözel etkinlikle kullanın vetriggerHandler

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

İşte jQuery tetikleyici işleyicisine bir bağlantı: http://api.jquery.com/triggerHandler/


1
son düşünce. yukarıda oldukça kapsamlı olması gerekse de: gizli bir girdi alanının değerini #content html ile güncelleyebilir ve ardından değişiklik olayını gizli giriş alanına bağlayabilirsiniz :) birçok seçenek
Kyle

7
+1 "İşlemin nerede gerçekleştiğini bulun ve ardından ihtiyacınız olanı oraya ekleyin." Herhangi bir hack / eklenti olmadan sorunumu 2 saniyede düzeltti :)
Hartley Brody

Burada önerdiğim tek değişiklik bind, işleyicinizin bir bool.
Serj Sagan

15

Tarayıcı, <div>öğeler için onchange olayını tetiklemeyecektir .

Sanırım bunun arkasındaki mantık, javascript tarafından değiştirilmedikçe bu unsurların değişmeyeceğidir. Öğeyi zaten kendiniz değiştirmeniz gerekiyorsa (bunu yapan kullanıcı yerine), öğeyi değiştirirken aynı zamanda uygun eşlik eden kodu çağırabilirsiniz, örneğin:

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

Bunun gibi bir olayı manuel olarak da tetikleyebilirsiniz:

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

Bu çözümlerden hiçbiri sizin durumunuz için işe yaramazsa, lütfen özellikle neyi başarmaya çalıştığınız hakkında daha fazla bilgi verebilir misiniz?


11
Bu, tüm javascript'i yazdığınızı varsayar, durum böyle olmayabilir.
Myster

TEŞEKKÜR EDERİM!!!! Bu, 6 saattir baktığım bir sorunu çözmeme yardımcı oldu.
Jordan Parmer

Tam olarak ihtiyacım olan şey.
smac89

15

peki ya http://jsbin.com/esepal/2

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

Bu etkinlik, Mutation Observer API'nin lehine kullanımdan kaldırıldı


1
Fena fikir değil, ne kadar desteği olduğunu merak etmeme rağmen. developer.mozilla.org/en/DOM/DOM_event_reference/…
Elzo Valugi

Değişiklikler için belirli bir öğeyi nasıl izlersiniz? Şu anda belge tüm sayfayı izliyor.
Patoshi パ ト シ




3

Kesinlikle bir jQuery cevabı değildir - ancak hata ayıklama için bahsetmek yararlıdır.

Firebug'da DOM ağacındaki bir öğeyi sağ tıklayabilir ve 'Öznitelik Değişikliğinde Kırılma' ayarlayabilirsiniz:

Öznitelik Değişikliğinde Kesinti vurgulanmış olarak Firebug'da öğe sağ tıklama

Bir betikte bir öznitelik değiştirildiğinde, hata ayıklama penceresi görünecek ve neler olduğunu takip edebilirsiniz. Aşağıda öğe ekleme ve öğe kaldırma seçeneği de vardır (ekran görüntüsündeki açılır pencere tarafından yardımcı olmadan engellenmiştir).


1
Bu yardımcı oldu, ancak tam olarak istediği şey değil. Bu, bir sınıf değiştiğinde veya bir stil özelliği eklendiğinde veya değiştirildiğinde gibi şeyleri algılayacaktır. Düğümün içindeki içerik değiştiğinde kontrol etmez. Örneğin, bir yerde bir javascript <span> merhaba </span> yerine <span> Dünya </span> düğümünü değiştirirse, bu onu algılamayacaktır
Joshua Soileau



1

Genellikle bunu başarmanın basit ve etkili bir yolu, DOM'u ne zaman ve nerede değiştirdiğinizi takip etmektir.

Bunu, her zaman DOM'un değiştirilmesinden sorumlu olan bir merkezi işlev oluşturarak yapabilirsiniz. Daha sonra bu işlevin içinden değiştirilen eleman üzerinde ihtiyacınız olan temizliği yaparsınız.

Yeni bir uygulamada, anında eyleme geçmem gerekmedi, bu nedenle, değiştirilmiş öğelere bir sınıf eklemek için handly load () işlevi için bir geri arama kullandım ve ardından tüm değiştirilmiş öğeleri birkaç saniyede bir setInterval zamanlayıcıyla güncelledim.

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

O zaman istediğiniz gibi halledebilirsiniz - örneğin

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

3
Bu, tüm javascript'i yazdığınızı varsayar, durum böyle olmayabilir.
Myster

1

Html (veya herhangi bir) işlevine bir geri arama seçeneği ekleyebilirsiniz:

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

Demo burada.

Değişikliği bazı unsurlarda yaparsınız, unsur sizin yakalamanız gereken bir şey tarafından değişmeye zorlanmaz.


Bu sorunu bugün çözmek zorunda kaldım. Aslında html () olarak adlandırılan kodu düzenleyemedim çünkü 3. parti kitaplıkta. Bunun değiştirilmiş bir versiyonu benim için mükemmeldi. Bunu yaptım: $ .fn.oldHtml = $ .fn.html (); $ .fn.html = function (e) {var sonuç = this.oldHtml (e); this.trigger ('afterHtmlChange', e);} Artık istediğim olayları herhangi bir öğe üzerindeki yeni oluşturulan afterHtmlChange olayına bağlayabilirim, bu herhangi bir şey jQuery'nin html () fn'sini çağırdığında tetiklenir.
Daniel Howard

Hay aksi, küçük bir hata. Yukarıdaki yorumumdaki Fn şöyle olmalıdır: function (e) {var sonuç = this.oldHtml (e); this.trigger ( 'afterHtmlChange', e) dönüş sonucu;}
Daniel Howard

0

Bir olaydaki bir öğenin değişikliğini kontrol edecek bir pasaj yazdım.

Dolayısıyla, üçüncü taraf javascript kodu veya başka bir şey kullanıyorsanız ve tıkladığınızda bir şeyin göründüğünü veya değiştiğini bilmeniz gerekiyorsa, o zaman yapabilirsiniz.

Aşağıdaki ön bilgi için, bir düğmeyi tıkladıktan sonra bir tablo içeriğinin ne zaman değişeceğini bilmeniz gerektiğini varsayalım.

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

Sözde Kod:

  • Bir düğmeyi tıkladığınızda
  • Değiştirmeyi beklediğiniz öğenin html'si yakalanır
  • daha sonra öğenin html'sini sürekli kontrol ederiz
  • html'nin farklı olduğunu bulduğumuzda kontrolü durdururuz

0

Bunu Mutasyon Olaylarını kullanarak başarabiliriz . Www.w3.org'a göre, mutasyon olay modülü, öznitelik ve metin değişiklikleri de dahil olmak üzere bir belgenin yapısındaki herhangi bir değişikliğin bildirimine izin vermek için tasarlanmıştır. Daha fazla detay için MUTASYON ETKİNLİKLERİ

Örneğin :

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

Bu bir süredir kullanımdan kaldırıldı. Bir kullanmalıdır Mutasyon Gözlemcisi (aynı kavram)
Carles Alcolea

-3

Mümkün değil, yani içeriğin değiştiğine inanıyorum, ancak bu kesinlikle x-browser değil

Arka planda çirkin bir zaman aralığı olmadan mümkün olmadığını söylemeliyim!


21
hiçbir şey imkansız değildir!
jrharshath
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.