2014-09-25 53 views
3

我試圖實現與利用代理事件RactiveJS一個簡單的可拖動DIV(上鼠標按下,向上移動,出來)RactiveJS拖動利用的MouseEvent

JSFiddle作品就好了,但是當用戶移動鼠標太快拖動停止。這很簡單,因爲我的情況下的mouseevent處理程序位於DIV標籤上,而不是正文或文檔元素。我的最終想法是創建一個滑塊組件,但是我正在尋求提供最好的用戶體驗,並使其更像JQuery的可拖動。

模板:

<div class="rect {{drag ? 'dragging' : ''}}" 
     on-mousedown="startDrag" 
     on-mouseup="stopDrag" 
     on-mouseout="stopDrag" 
     on-mousemove="drag" 
     style="top:{{top}}px; left:{{left}}px;"> 
</div> 

Ractive例如:

var ractive = new Ractive({ 
    el: "#content", 
    template: "#template", 
    data: {left:20,top:80} 
}); 
ractive.on({ 
    startDrag : function (event) { 
     this.set({ 
      'drag': true, 
      'mouseX': event.original.clientX - this.get('left'), 
      'mouseY': event.original.clientY - this.get('top') 
     }); 
    }, 
    stopDrag : function (event) { 
     this.set('drag', false); 
    }, 
    drag : function (event) { 
     if(this.get('drag')) { 
      var x = event.original.clientX, 
       y = event.original.clientY; 
      this.set({ 
       top: y - this.get('mouseY') , 
       left: x - this.get('mouseX') 
      }); 
      event.original.stopPropagation(); 
     } 
    } 
}) 

如何改善上面的代碼?

回答

5

通常mousemovemouseend需要在document上。我發現在Ractive中,裝飾器通常更適合拖動。這裏有一個例子,讓你去(http://jsfiddle.net/h9j2hdyj/1/):

<div class="rect noSelect {{ dragging ? 'dragging' : ''}}" 
    decorator='drag:"position"' 
    style="{{#position}}top:{{top}}px;left:{{left}}px{{/}}"> 
</div> 

裝飾:

Ractive.decorators.drag = function(node, keypath){ 

    var ractive = this, initial, begin, startPos; 

    node.addEventListener('mousedown', start, false) 

    function listenOnDocument(){ 
     document.addEventListener('mousemove', move, false) 
     document.addEventListener('mouseup', unlistenOnDocument, false) 
    } 

    function unlistenOnDocument(){ 
     document.removeEventListener('mousemove', move, false) 
     document.removeEventListener('mouseup', end, false) 
    } 

    function start(e){ 
     begin = { x: e.x, y: e.y } 
     startPos = ractive.get(keypath) 
     startPos = { x: startPos.left, y: startPos.top } 
     ractive.set('dragging', true) 
     listenOnDocument() 
     e.preventDefault() 
     e.stopPropagation() 
    } 

    function move(e){ 
     ractive.set(keypath, { 
      left: startPos.x + (e.x - begin.x), 
      top: startPos.y + (e.y - begin.y) 
     }) 
     e.preventDefault() 
     e.stopPropagation() 
    } 

    function end(){ 
     unlistenOnDocument() 
     ractive.set('dragging', false) 
    } 

    return { 
     update: function(pos){ 
      console.log(pos) 
      position = pos 
     }, 
    teardown: function(){ 
     node.removeEventListener('mousedown', start, false) 
     end() 
    } 
    } 

} 
+0

謝謝馬蒂!這非常有幫助。也許我們應該把它添加到Ractive的網站裝飾器部分作爲裝飾器有用的另一個例子 – 2014-09-26 07:28:00

+1

修復了小提琴:http://jsfiddle.net/h9j2hdyj/7/ – ceremcem 2018-02-13 01:56:46

2

另一種選擇是使用ractive-touch插件的pan事件 - 他們使用Hammer.js引擎蓋下所以他們鼠標和觸摸友好。

+0

感謝Rich的建議,我會定義試試看。我也喜歡Marty的狂熱裝飾者。 – 2014-09-26 06:34:49