2

私は独自のクラス (SVG オブジェクト用) を構築しており、最近イベント処理を追加し始めました。標準モデルに従って、このタイプの相互作用が欲しい

svgobj.bind('click', function(e){
  // do stuff here on click with svgobj
});

jQuery を使用してイベントをアタッチしていますが、この「バインド」は jQuerybind()メソッドではなく、svgobj は jQuery オブジェクトではありません

私が遭遇している問題は、複数のオブジェクトを作成すると、svgobjその匿名関数内の参照がsvgobj、イベントが発生したオブジェクトではなく、最後に作成されたものになることです。したがって、たとえば、イベントがオブジェクトのステータスの変更を処理する場合、どのオブジェクトをクリックしても、最後のオブジェクトのみがステータスを変更します。

私はこれが閉鎖の問題であることを知っており、同僚の助けを借りて修正を見つけましたが、それはひどく醜いものです。これには、関数を自己実行型の匿名関数でラップすることが含まれます。この関数に正しい関数を渡しsvgobj、元の関数を返します。例を次に示します。

svgobj.bind('click', (function(target){
    return function(e){
      // do stuff here on click with target, i.e. the correct svgobj
    }
  })(svgobj)
);

それは機能し、この例をhttp://jsfiddle.net/2late2die/98te2/で見ることができます。赤/緑の領域をクリックすると、ドラッグ イベント (円の部分) とステータス変更イベントをテストできます。

この問題を解決するより良い方法はありますか? イベントで何かをするたびに、2 つの匿名関数を使用する必要がないようにしたいと思います。おそらく、自己実行関数を最初にイベントを呼び出すメソッドに移動する方法があるので、「外側では」1つの通常の関数がパラメーターとして渡されているように見えますか?

4

2 に答える 2

1

使うこと.bindで(使い方からjQueryを想定しています)、関数this内が対象になるので、関数内で変数を使う必要がなくなるはずです。svobj

svgobj.bind('click', function (e) {
  // do stuff here on click with `this` or `$(this)`
});

svgobj現在の状態の正確なコピーが.bind必要な場合は、それを独自のスコープにキャプチャして、変更から保護する必要があります。あなたが「醜い」と説明したラムダ関数の方法は、おそらくこれを達成する最も簡単な方法です。

于 2013-01-23T18:31:37.677 に答える
1

そこではかなり標準的な規則を使用していますが、そのままではかなり慣用的なJavaScriptと見なされます。

本当にきれいにしたい場合は、このように無名関数を分割できます

function getCallBack(target){
   return function(e){
       //Do stuff with target
   }
}

svobj.bind('click',getCallBack(svobj));

全体的には長くなりますが、バインド呼び出しがクリーンアップされ、コメントを追加してコールバック関数の使用を明確にすることができます。そのコードの再利用を計画している場合にも役立ちます。

アップデート

カスタムバインド関数を使用しているように見えるので、内部関数内で設定して`var that = this;から参照することにより、内部クロージャー内の元の this 値をキャプチャできます。使用する内部関数のレベルに関係なく、常に呼び出し元のオブジェクトを参照します。thatthat

ただし、jQuery を使用しているようですので、jQuery bind 関数を使用して、自分で簡単にすることをお勧めします。

于 2013-01-23T18:28:37.293 に答える