29

私の目的は、入力値を監視し、その値がプログラムによって変更されたときにハンドラーをトリガーすることです。最新のブラウザでのみ必要です。

を使用して多くの組み合わせを試しdefinePropertyましたが、これが私の最新の反復です。

var myInput=document.getElementById("myInput");
Object.defineProperty(myInput,"value",{
    get:function(){
        return this.getAttribute("value");
    },
    set:function(val){
        console.log("set");
        // handle value change here
        this.setAttribute("value",val);
    }
});
myInput.value="new value"; // should trigger console.log and handler

valueこれは私が期待しているように見えますが、既存の値プロパティをオーバーライドし、 (属性とプロパティ)の二重ステータスで遊んでいるので、ハックのように感じます。またchange、変更されたプロパティが気に入らないと思われるイベントを中断します。

私の他の試み:

  • setTimeout/setInterval ループですが、これもクリーンではありません
  • さまざまなwatchポリフィルobserveがありますが、入力値プロパティで壊れます

同じ結果を達成するための適切な方法は何でしょうか?

ライブデモ: http://jsfiddle.net/L7Emx/4/

[編集] 明確にするために: 私のコードは、他のアプリケーションが更新をプッシュできる入力要素を監視しています (たとえば、ajax 呼び出しの結果として、または他のフィールドの変更の結果として)。他のアプリケーションが更新をプッシュする方法を制御することはできません。私は単なるオブザーバーです。

[編集 2] 「最新のブラウザー」の意味を明確にするために、IE 11 および Chrome 30 で動作するソリューションに非常に満足しています。

[更新]受け入れられた回答に基づいてデモを更新: http://jsfiddle.net/L7Emx/10/

@mohit-jain が提案する秘訣は、ユーザー インタラクション用に 2 番目の入力を追加することです。

4

7 に答える 7

1

あなたはすでにウォッチ/オブザーブなどにポリフィルを使用しているので、この機会にAngularjsを提案させてください。

まさにこの機能を ng-models の形で提供します。モデルの値にウォッチャーを配置し、値が変更されたときに他の関数を呼び出すことができます。

これは非常にシンプルですが、必要なものに対する実用的なソリューションです。

http://jsfiddle.net/RedDevil/jv8pK/

基本的に、テキスト入力を作成してモデルにバインドします。

<input type="text" data-ng-model="variable">

次に、コントローラーのこの入力で angularjs モデルにウォッチャーを配置します。

$scope.$watch(function() {
  return $scope.variable
}, function(newVal, oldVal) {
  if(newVal !== null) {
    window.alert('programmatically changed');
  }
});
于 2013-10-14T16:52:29.810 に答える
1
于 2013-10-14T17:04:46.537 に答える
0

少し前に次のGistを書きました。これにより、ブラウザー間 (IE8+ を含む) でカスタム イベントをリッスンできます。

私がonpropertychangeIE8 でどのようにリッスンしているか見てみましょう。

util.listenToCustomEvents = function (event_name, callback) {
  if (document.addEventListener) {
    document.addEventListener(event_name, callback, false);
  } else {
    document.documentElement.attachEvent('onpropertychange', function (e) {
    if(e.propertyName == event_name) {
      callback();
    }
  }
};

IE8 ソリューションがクロス ブラウザーで機能するかどうかはわかりませんが、入力eventlistenerのプロパティvalueに偽物を設定し、 の値がvalueによってトリガーされると、コールバックを実行できますonpropertychange

于 2013-10-20T19:51:31.537 に答える
0

これを行う方法があります。このための DOM イベントはありませんが、オブジェクト プロパティの変更をトリガーする JavaScript イベントがあります。

document.form1.textfield.watch("value", function(object, oldval, newval){})
                ^ Object watched  ^                      ^        ^
                                  |_ property watched    |        |
                                                         |________|____ old and new value

コールバックでは、何でもできます。


この例では、この効果を確認できます ( jsFiddleを確認してください)。

var obj = { prop: 123 };

obj.watch('prop', function(propertyName, oldValue, newValue){
    console.log('Old value is '+oldValue); // 123
    console.log('New value is '+newValue); // 456
});

obj.prop = 456;

変更すると、リスナーobjがアクティブになります。watch

このリンクに詳細があります: http://james.padolsey.com/javascript/monitoring-dom-properties/

于 2013-10-15T10:07:38.413 に答える