2016-04-27 7 views
1

オブジェクトループ内のforキーを使用してイベントのオブジェクトをバインドしようとしました。オブジェクトとのイベントのバインド

events = { 
    mouseup:function(data){console.log(data)}, 
    mousedown:function(data){console.log(data)}, 
} 
for (var key in events) { 
      console.log('binding: ' + key) ; 
      $('body').on(key ,function(data){ 
       console.log(key ,data); 
      }) 

} 

ただし、最後のオブジェクト(mousedown)は両方のイベントにバインドされます。誰もが理由を説明できますか?

完全な例については、フィドルをご覧ください。

https://jsfiddle.net/2439rw4a/

答えて

2

Yeap - keyは、イベントが発生するまでは評価されず、その時点でそれが上書きされ、「マウスダウン」を残ってきたので。

イベントバインド時に現在の値keyを分離する必要があります。次の2つのオプションがあります。

1)直ちに実行される関数クロージャを使用して送信します。これにより、イベントコールバックの範囲内でローカルコピーkeyが取得されます。

for (var key in events) { 
    $('.box').on(key, (function(key) { return function(data){ 
     console.log(key); 
    }; })(key)); 

2)イベントデータを介してそれを送る

for (var key in events) { 
    $('.box').on(key, {key: key}, function(evt){ 
     console.log(evt.data.key); 
    }); 
0

それは、そのようなバグのタイプの良い例です。

keyはループの最後のキーと等しいので、このような動作が発生します。forループ。

events = { 
    mouseup:function(data){console.log(data)}, 
    mousedown:function(data){console.log(data)}, 
} 
for (var key in events) { 
      console.log('binding: ' + key) ; 
      $('.box').on(key ,function(data){ 
       console.log(event.type); 
      }) 

} 

jsfiddle:イベントが発生し、keyの値は、最後のキーされるまでにhttps://jsfiddle.net/2439rw4a/

0

すべてが正常に動作し 、ちょうどイベントタイプではなく、keyを表示するには、コンソールログを変更します。コードの実行は、次のようになります

key = 'mouseup'; 

$('body').on(...); 

key = 'mousedown'; 

$('body').on(...); 

// By this time, key = 'mousedown' 
// Mouse is clicked. 
// When even fires, it looks for key which by now has the last key 

Object.keysarray.forEachを使用することを検討してください。この方法では、ハンドラは、key変数の代わりに、その反復時の値としてkeyを参照します。

Object.keys(events).forEach(function(key){ 
    console.log('binding: ' + key) ; 
    $('body').on(key ,function(data){ 
    console.log(key ,data); 
    }) 
}); 
関連する問題