web-dev-qa-db-ja.com

JSイベント:テキスト入力での値変更イベントのフック

ユーザーではなくスクリプトによって内容が変更されるテキスト入力があります。したがって、値が変更されたときにイベントを発生させたいと思います。そのための適切なイベントが見つかりません。 this on StackOverflow も見つけましたが、これは私が探している解決策ではありません。

これをjQueryおよび値が次のように設定されているテキスト入力で機能させる方法:

myTextControl.value = someValue

ここで、新しい値を確認するためにイベントを発生させたいと思います。

31
Esteban Feldman

そのための適切なイベントが見つかりません。

ええ、ありません。

DOM変異イベント がありますが、それらはブラウザー間で適切にサポートされておらず、フォームの値が属性に反映されていないため、とにかく起動しません(IEバグのため)。

Mozillaのみで、JavaScript watch をvalueプロパティに設定して、スクリプトによる変更をキャッチできます。 IEのみで、JScript onpropertychange ハンドラーを設定して、スクリプトによる変更とユーザー主導の変更の両方をキャッチできます。他のブラウザーでは、独自のインターバルポーラーを使用して、変更を探します。

function watchProperty(obj, name, handler) {
    if ('watch' in obj) {
        obj.watch(name, handler);
    } else if ('onpropertychange' in obj) {
        name= name.toLowerCase();
        obj.onpropertychange= function() {
            if (window.event.propertyName.toLowerCase()===name)
                handler.call(obj);
        };
    } else {
        var o= obj[name];
        setInterval(function() {
            var n= obj[name];
            if (o!==n) {
                o= n;
                handler.call(obj);
            }
        }, 200);
    }
}

watchProperty(document.getElementById('myinput'), 'value', function() {
    alert('changed!');
});

これは非常に不十分です。 Mozillaでのユーザー主導の変更に応答せず、IEでオブジェクトごとに1つの監視プロパティのみを許可します。他のブラウザーでは、ハンドラー関数は実行フローのかなり後で呼び出されます。

トラップする変更を監視できるように、valueをsetValueラッパー関数を呼び出すように設定するスクリプトの部分を書き直す方がほぼ確実です。

19
bobince

通常のイベントリスナーを入力フィールドに追加できます。 (jQueryを使用)

$(myTextControl).change(function() {
    ...
    /* do appropriate event handling here */
    ...
});

入力値を変更するJavaScriptがユーザーによって制御されていないことを考えると、難しくなります。次の2つのオプションがあります。

1。)クロスブラウザ互換:値が変化したかどうかを継続的にチェックする関数を使用して、入力値のポーリングを実装します。 (これらの線に沿った何か)。

//at beginning before other scripts changes the value create a global variable
var oldValue = myTextControl.value;

function checkIfValueChanged() {
    if(myTextControl.value != oldValue) {
        $(myTextControl).trigger("change");
        clearInterval(checker);
    }
}

//every 500ms check if value changed
var checker = setInterval('checkIfValueChanged()', 500);

:スクリプトまたはユーザーも値を変更できる場合は、変更イベントを複数回トリガーしないように、これをキャッチするために何かを実装する必要があります。

外部スクリプトによって値が複数回変更される可能性がある場合は、キャンセルするのではなく、interval関数を実行してoldValueを更新するだけです。

2。)AFAIKすべてのブラウザーでまだサポートされていません(?サポートする必要があるブラウザーでテストしてください)

特別なDOM Level 3Eventにバインドできます:DOMAttrModified(Firefoxでは、おそらく他の人もOperaも持っていると思います、Safari ??、Chrome ??)およびin = IEもちろん、名前はpropertychangeと異なります(これは独自仕様であり、W3Cの動作とは異なります)

理想的には、2つのオプションを組み合わせて、DOMAttrModifiedまたはpropertychangeのサポートがあるかどうかを確認し、それに応じて使用するか、ポーリングソリューションにフォールバックできます。


リンクを読む

W3C DOM変異イベント

W3C DOMAttrModifiedイベント

MSDN DHTML propertychangeイベント

jQuery CSSプロパティ監視プラグインが更新されました

最後のリンクは、基本的にすでに私が説明したことを実行するjQueryプラグインを作成している人です(参照として提供されているだけで、私には期待されていません)。

5
jitter