jQueryで要素コンテンツの変更を検出する


113

change() 関数は機能し、フォーム要素の変更を検出しますが、DOM要素のコンテンツが変更されたことを検出する方法はありますか?

これ#contentは、フォーム要素でない限り機能しません

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

私はこれを次のようなときにトリガーします:

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

またhtml()append()関数にはコールバックがありません。

助言がありますか?


古い質問ですが、エレガントな解決策について私の回答を確認してくださいstackoverflow.com/a/23826615/744975
Andrew Atkinson '23

回答:


26

これらは突然変異イベントです。

私はjQueryでミューテーションイベントAPIを使用していませんが、大まかな検索でGitHubのこのプロジェクトに移動しました。私はプロジェクトの成熟度を知りません。


17
このミューテーションイベントプラグインは、jQueryミューテーションメソッドにイベントをフックするだけなので機能しません。jQuery自体が要素を変更しようとしたときに起動されますが、要素がjQueryの外部から変更された場合には起動されません。ドキュメントの変更は監視しません。代わりに、この小さなプラグインをチェックアウト:stackoverflow.com/questions/3233991/jquery-watch-div/...
セバスティアンGrignoli

10
試したことのないライブラリへのリンクをグーグルして投稿することは、あまり役に立ちません。(私はdownvoting時に促されたのでコメント。)
ストップ毀損モニカチェッリオ

27
突然変異イベントは非推奨です。それらを使用しないでください。
ブロックアダムス

突然変異イベントの代替は、MutationObserversのようです。
WoodrowShigeru 2015

69

私はこの投稿が1年前であることを知っていますが、同様の問題を抱えている人々に別の解決策を提供したいと思います。

  1. jQuery changeイベントは、ユーザー入力フィールドでのみ使用されます。何か他のものが操作される場合(divなど)、その操作はコードから行われるためです。したがって、操作が発生する場所を見つけ、そこに必要なものを追加します。

  2. しかし、それが何らかの理由でできない場合(複雑なプラグインを使用しているか、「コールバック」の可能性が見つからない場合)、私が提案するjQueryアプローチは次のとおりです。

    a。単純なDOM操作の場合は、jQueryチェーンとトラバースを使用します。$("#content").html('something').end().find(whatever)....

    b。他に何かしたい場合は、jQueryのbindカスタムイベントを使用し、triggerHandler

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

jQueryトリガーハンドラーへのリンクは次のとおりです。http//api.jquery.com/triggerHandler/


1
最終的な考え。上記はかなり包括的であるはずですが、非表示の入力フィールドの値を#content htmlの値で更新し、変更イベントを非表示の入力フィールドにバインドできます:)多くのオプション
Kyle

7
+1「操作が行われる場所を見つけ、そこに必要なものを追加します。」ハック/プラグインなしで2秒で私の問題を修正:)
Hartley Brody

ここで提案する唯一の変更は、bindがハンドラーがを返すことを期待していることboolです。
Serj Sagan

15

ブラウザは<div>要素のonchangeイベントを発生させません。

これの背後にある理由は、JavaScriptで変更しない限り、これらの要素は変更されないためだと思います。要素を(ユーザーが実行するのではなく)自分で変更する必要がある場合は、次のように、要素を変更すると同時に適切な付随するコードを呼び出すだけです。

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

次のようなイベントを手動で起動することもできます。

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

これらの解決策のどちらもあなたの状況でうまくいかない場合は、具体的に達成しようとしていることについて、詳細を教えていただけませんか?


11
これはあなたがすべてのJavaScriptを書いたと仮定していますが、そうではないかもしれません。
ミスター

ありがとうございました!!!!これは、私が6時間ずっと見つめていた問題を解決するのに役立ちました。
ジョーダンパーマー2013年

まさに私が必要としたもの。
smac89 2017

15

http://jsbin.com/esepal/2はどうですか

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

このイベントは、Mutation Observer APIを支持して廃止されました


1
どれだけのサポートがあるのか​​しら。developer.mozilla.org/en/DOM/DOM_event_reference/...
Elzo Valugi

特定の要素の変更をどのように監視しますか?現在、ドキュメントはページ全体を監視しています。
Patoshiパトシ




3

これは厳密にはjQueryの回答ではありませんが、デバッグについて言及するのに役立ちます。

Firebugでは、DOMツリーの要素を右クリックして、「属性の変更時にブレーク」を設定できます。

属性変更のブレークが強調表示されたFirebugで要素を右クリック

スクリプトで属性が変更されると、デバッグウィンドウが表示され、何が起こっているのかを追跡できます。要素の挿入と要素の削除のオプションも以下にあります(スクリーングラブのポップアップではわかりにくいです)。


1
これは役に立ちますが、正確には彼が求めていたものではありません。これにより、クラスが変更されたときや、スタイル属性が追加または変更されたときなどが検出されます。ノード内部の内容がいつ変更されたかはチェックしません。たとえば、JavaScriptがノードを<span> hello </ span>から<span> World </ span>に変更した場合、これはそれを検出しません
Joshua Soileau



1

多くの場合、これを実現する簡単で効果的な方法は、DOMを変更しているときと場所を追跡することです。

これを行うには、常にDOMの変更を担当する1つの中心的な関数を作成します。次に、この関数内から変更された要素に必要なクリーンアップを実行します。

最近のアプリケーションでは、すぐにアクションを実行する必要がなかったので、handly load()関数のコールバックを使用して、変更された要素にクラスを追加し、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イベントに任意のイベントをバインドできます。これは、何かがjQueryのhtml()fnを呼び出すたびに発生します。
Daniel Howard

おっと、ちょっとした間違い。上記の私のコメントのFnは次のようになります:function(e){var result = this.oldHtml(e); this.trigger( 'afterHtmlChange'、e); return result;}
Daniel Howard

0

イベントの要素の変更をチェックするスニペットを書きました。

したがって、サードパーティの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

これを達成するには、Mutation Eventsを使用します。www.w3.orgによると、ミューテーションイベントモジュールは、attrやテキストの変更を含む、ドキュメントの構造の変更を通知できるように設計されています。詳細については、MUTATION EVENTS

例えば ​​:

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

これはしばらくの間推奨されていません。ミューテーションオブザーバーを使用する必要があります(同じコンセプト)
Carles Alcolea 2017

-3

不可能です。つまり、コンテンツ変更イベントがあると思いますが、Xブラウザではありません。

バックグラウンドで厄介な間隔がぎゅうぎゅうと鳴り響くまで、私は不可能だと言えますか?


21
不可能なものは何もない!
jrharshath 2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.