2017-12-01 42 views
0

jqueryを使わずにjqueryプラグインを書き直そうとしていますが、なぜ関数でイベントが更新されないのかわかりません'引数を持つ.bind()を使用しています。私は次のように問題を単純化している:あなたが青のdivにクリックしたとき関数の引数で.bind()を使用すると、mousedownでイベントが更新されない

function IMdraw(div) { 
 
\t this.div = div 
 
\t this.div.addEventListener('mousedown', this.mousedown.bind(this)); 
 
} 
 

 
IMdraw.prototype = { 
 

 
\t onMouseMove: function (fn) { 
 
\t \t this.moveHandler = fn; 
 
\t \t this.div.addEventListener('mousemove', this.moveHandler, false); 
 
\t }, 
 
\t 
 
\t move1: function(e, arg) { 
 
\t \t console.log('move1') 
 
\t \t console.log(e.offsetX); 
 
     console.log(e.offsetY); 
 
\t }, 
 

 
\t move2: function(e) { 
 
     console.log('move2') 
 
\t console.log(e.offsetX); 
 
     console.log(e.offsetY); 
 
\t }, 
 

 

 
\t mousedown: function(e) { 
 
     var arg = 3; 
 
     this.onMouseMove(this.move1.bind(this)); 
 
     this.onMouseMove(this.move2.bind(this, e, arg)); 
 

 
\t }, 
 

 
} 
 

 
var obj = new IMdraw(document.querySelector('div'));
<div style="width:500px; height:500px; background: blue;"> 
 
    </div>

を見ることができるようにし、MOVE2機能では、divの中にカーソルを動かし、offsetXとoffsetYはありません更新はしませんが、move1関数で行います。

このように動作する理由はありますか?私は.bind()を間違って使っていると思います。

+0

その電子とのarg引数を削除し、this.arg –

+0

は、残念ながら、これはプラグインでは最善の解決策ではないとして、あなたの引数を作る、私はむしろとしてそれを持って、それを通過したいですプロトタイプのグローバル変数。 – user4282812

答えて

0

問題は、bindコールがイベントオブジェクトのイベントコールバック関数への自動渡しを妨げていることです。 move1

  • 、あなたは何を渡していないので、e正しく に自動的にイベント コールバック関数に渡されるmousemoveイベントを指しています。 argが渡されなかったので、arg(内move1)はundefinedとなります。
  • move2では、自分の引数を渡すことでイベントオブジェクトの自動渡しを妨げています。 の引数がmousedownイベントのイベントオブジェクトです。 は、mousemoveが発生したときに更新されないため、マウスがクリックされたときのオフセットが常に表示されます。あなたはargmove2に渡しました。それは利用可能でした。

ソリューションは、すべてのイベントオブジェクトを渡し、それが通常であるとそれが自動的に渡されてみましょうとだけあなたが必要とする余分なデータ(あなたのケースでarg)を渡すことではないことですしかし引数(複数可)この場合、関数が受け取った最初のものが渡され、イベントはLAST(通常発生するものとは逆の)になります。

MDN FROM:

構文fun.bind(thisArg[, arg1[, arg2[, ...]]])

パラメータ

thisArg

バインドされた関数が呼び出されたときに、このパラメータとしてターゲット関数 に渡される値です。バインドされた 関数がnew演算子を使用して構築されている場合、値は無視されます。

arg1、arg2、...ターゲット関数を呼び出すバインド機能 に提供引数に先頭に追加から

引数。

実用的な解決策があります。私はonmousemoveの代わりにaddEventListenerを使用するように少し修正を加えました。これはより現代的で標準ベースです。

function IMdraw(div) { 
 
\t this.div = div; 
 
\t this.div.addEventListener('mousedown', this.mousedown.bind(this)); 
 
} 
 

 
IMdraw.prototype = { 
 
\t onMouseMove: function (fn) { 
 
\t \t this.div.addEventListener('mousemove', fn); 
 
\t }, 
 
\t 
 
\t move1: function(arg, e) { 
 
\t \t console.log('move1'); 
 
\t console.log(e.offsetX, "Passed argument: " + arg); 
 
    console.log(e.offsetY, "Passed argument: " + arg); 
 
\t }, 
 

 
\t move2: function(arg, e) { 
 
    console.log('move2'); 
 
\t console.log(e.offsetX, "Passed argument: " + arg); 
 
    console.log(e.offsetY, "Passed argument: " + arg); 
 
\t }, 
 

 
\t mousedown: function(e) { 
 
    console.log(this.div); 
 
    var arg = 3; 
 
    // The e argument represents the mousedown event that was fired. It only happens 
 
    // once, when you click the mouse. It won't happen again when you move the mouse 
 
    // so the values associated with it don't change on move1 and move2. 
 
    // Instead, don't pass the event object at all (let that happen organically as it 
 
    // normally does) and pass just the extra data you want to pass. This extra argument 
 
    // will be the FIRST argument recieved by the bound function and the event will be 
 
    // the SECOND. 
 
    this.div.addEventListener("mousemove", this.move1.bind(this, arg)); 
 
    this.div.addEventListener("mousemove", this.move2.bind(this, arg)); 
 
\t } 
 
} 
 

 
var obj = new IMdraw(document.querySelector('div'));
<div style="width:500px; height:500px; background: blue;"> 
 
    </div>

+0

しかし、arg変数はmove2関数に渡されません。むしろarg変数を渡してプロトタイプのグローバル変数として持つことを望みたいと思います。 – user4282812

+0

@ user4282812問題を完全に説明するための答えと、実行しようとしていることを実行できる解決策を更新しました。 –

+0

よろしく、ありがとう@Scott! – user4282812

関連する問題