2016-05-16 5 views
0

動作しないデモJS:私は、「追加」との「削除」を参照してください。はそれに基づいて

val panelElem = document.getElementById(COMPONENT_ID).asInstanceOf[HTMLDivElement] 
    if (draggable == null) { 
    draggable = new Draggable(panelElem) 
    } 

:私はそれが好きで使用するクライアントコードからhttp://jsfiddle.net/wfbY8/737/

class Draggable(element: HTMLDivElement) { 

    var offX: Double = 0 
    var offY: Double = 0 

    val divMove = (e:MouseEvent) => { 
    //element.style.position = 'absolute'; 
    element.style.top = (e.clientY-offY) + "px" 
    element.style.left = (e.clientX-offX) + "px" 
    } 

    val mouseDown = (e:MouseEvent) => { 
    offY = e.clientY - element.offsetTop 
    offX = e.clientX - element.offsetLeft 
    window.addEventListener("mousemove", divMove, useCapture = true) 
    println("added") 
    } 

    val mouseUp = (e:MouseEvent) => { 
    window.removeEventListener("mousemove", divMove, useCapture = true) 
    println("removed") 
    } 

    def addListeners(){ 
    element.addEventListener("mousedown", mouseDown, useCapture = false) 
    window.addEventListener("mouseup", mouseUp, useCapture = false) 

    } 

    addListeners() 

} 

を私のログ。しかし、(mouseUp上の)リスナーからmousemoveイベントを削除しなかったかのように、要素はまだ移動可能です(マウスを押さずに移動すると)。

あなたが効果的にaddremoveごとに個別のJS関数にScalaの関数(ラムダ)を変換しているので...

答えて

2

これはなぜ起こるのだろうか。 Scala.jsでは、Scala関数は暗黙的にに変換され、必要に応じてがJS関数に変換されます。ただし、毎回異なるJS関数が変換されます(同じIDはありません)。したがって、削除しようとしている機能はと同じで、追加したものと同じではありません。もちろんその効果はありません。

これを修正するには、変換を早めに実行して、同じ機能を追加して削除することができます。そのためには、単にJS関数などval君の関数に明示的な型を追加します。

val divMove: js.Function1[MouseEvent, Unit] = (e:MouseEvent) => { 
    ... 
    } 

この方法では、JS関数にScalaの関数からの変換は一度だけ発生し、それが与えられているのと同じJS関数であり、 add-およびremoveEventListenerになります。

+0

はい。それは今働く。ちょうど1回起こることが予想される(変換)。それはvalなので。今はちょっとしたボイラープレートです – ses

+0

修正があると「val」なので一度起こります。しかし、 'val'は一度だけ評価され、* Scala *関数が保存されます。これは後で 'add/removeEventListener'に渡すときに変換されるだけなので、変換は数回実行されます。帰納法は、後でなく、 'val'(つまり1回)の評価の一部として変換を強制するだけです。 – sjrd

関連する問題