2

私はjavascriptの初心者で、次の問題に遭遇しています。これは、複数回検索した後、以前の回答で見つけることができませんでした(これが重複していないことを願っています)。

次のモジュール/クラスがあります。画面上でドラッグできるコンポーネントを実装しようとしているとしましょう。ユーザーが最初にクリックすると、のmousemoveイベントをリッスンしてwindow、ユーザーがマウスを動かしている場所を認識し始めます。ユーザーがマウスを離したら、ウィンドウのイベント リスナーを削除します。コードは非常に簡単で、iife の外でコーディングするだけで機能します。ただし、現在、removeEventListener単に機能しませんclousureスコープなどと関係があるのではないかと思いますが、完全に見逃しています。よろしくお願いします。コードは次のとおりです。

MyClass.js

 var myNamespace = myNamespace || {};
 (function(myNamespace){

 var onMouseDragDown = function(e){
          window.addEventListener("mousemove", onMouseDragMove,true);
          window.addEventListener("mouseup", onMouseDragUp,false);
       };

  var onMouseDragUp = function(e){
// This code executes, but the events CONTINUE to be triggered after removing the event listener

//The following lines do not seem to have any effect whatsoever even though they are executed when the user releases the mouse button
      window.removeEventListener("mousemove", onMouseDragMove, true);
      window.removeEventListener("mouseup", onMouseDragUp,false);
  };

  var onMouseDragMove = function(e){
      console.log('moving');
   };

   myNamespace.MyClass = function(param){
      this._param = param;
      this._div = document.createElement('div');  
      this._div = ....

      this._div.addEventListener('mousedown', onMouseDragDown.bind(this), false);
   }

   myNameSpace.MyClass.prototype.getDiv = function (){
      return this._div;
   }
)(myNameSpace);

索引.html

...

        function onCreateNewDocumentClicked(event){
            var myObject = new myNamepace.MyClass(someParams);
            document.body.appendChild(mdi.getDiv());
        }
4

2 に答える 2

5

イベント リスナーを削除するには、追加時に指定した正確な関数を指定する必要があります。
ここで何が起こっているかというと、bind() が毎回新しい関数を作成するため、実際には次のようになります。

someFunc.bind(someObj) !== someFunc.bind(someObj)

イベントリスナーを削除するには、追加時に提供した関数そのものを保存する必要があります。

後で削除できるように、リスナーを追加するときにリスナーを保存します。

var someListener = someFunc.bind(someObj);
element.addEventListener("--", someListener ) ;

// then, later :
element.removeEventListener('--', someListener);

ここで短いデモを作成しました。最初のボタンをクリックすると、「こんにちは」というアラートが表示されます。
bind の新しい呼び出しでリスナーを削除しても、リスナーは削除されないことがわかります。
次に、保存された関数を削除すると、仕事が行われます。

http://jsbin.com/EjevIQA/2/edit

編集:ドラッグする各 div にリスナーを追加/削除する必要はありません。代わりに、ウィンドウ内のクリックをリッスンし、イベントの「ターゲット」情報を利用して、どの div がクリックされたかを知ることができます。
クリックされた処理された div の場合、伝播を停止したり、デフォルトを防止したりする必要があるかもしれませんが、わかりません。

イベント ハンドラは次のようになります。

 function handleMouseDown(e) {
     // you might check here which button was clicked (0=left, 2=right)
     var button = e.button;
     // retrieve the target
     var target = e.target ;
     // check if the target is an object we want to drag
     ...
     ... return otherwise.
     // do some things to initialize the drag.
     ...
     // you might want to prevent the click to bubble / trigger default behaviour :
     e.stopPropagation();
     e.preventDefault();
 } 

ウィンドウまたはドキュメントオブジェクトで一度だけ設定します。

document.addEventListener("mousedown", handleMouseDown)

ここで小さなデモを作成しました。div をクリックして、それが識別されていることを確認してください:
http://jsbin.com/ilavikI/2/edit

于 2013-09-22T11:17:14.593 に答える