2016-05-16 39 views
0

js的演示:http://jsfiddle.net/wfbY8/737/可拖動的ScalaJS removeEventListener基於不起作用

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() 

} 

從客戶端的代碼,我用它喜歡:

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

我看到「添加」和「刪除」上我的日誌。但是對於我來說,元素仍然可以移動(當我移動鼠標而不按下它時),就好像我沒有從監聽器中移除mousemove事件一樣(在mouseUp上)。

我不知道爲什麼..

回答

2

這是因爲你有效地轉換斯卡拉功能(拉姆達)成JS函數單獨爲addremove。在Scala.js中,Scala函數隱式地根據需要將轉換爲JS函數。但是,轉換每次都會產生不同的JS函數(它不具有相同的標識)。因此,您嘗試刪除的功能不是與您添加的功能相同的,當然這不起作用。

您可以通過強制轉換髮生得更早來解決此問題,以便添加和刪除相同的功能。要做到這一點,只需一個明確的類型添加到您的功能val S作爲JS功能:

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

這樣,從斯卡拉功能JS功能轉換隻發生一次,而且是給予相同的JS功能到add - 和removeEventListener

+0

是的。它現在有效。只是預料會發生一次(轉換)..因爲它是val。現在它是一個小樣板 – ses

+0

它確實發生過一次,因爲它是一個帶有修正的'val'。但是沒有,'val'評估一次並存儲一個* Scala *函數。只有在將它傳遞給'add/removeEventListener'時纔會進行轉換,因此轉換會執行多次。歸屬只會強制轉換被用作評估'val'(因此,一次)而不是稍後的一部分。 – sjrd