div拖拽的問題

今天看到一篇寫的很好的文章,摘抄以下:css

思路

  1. 父盒子相對定位,子元素,也就是被拖拽的元素絕對定位
  2. 當鼠標在子元素中按下時,綁定鼠標移動事件,根據鼠標位置改變元素位置
    • 設置鼠標當前位置(offsetX,offsetY,這時和父的相對位置)爲元素的中心位置
    • 移動時改變位置css中的left爲offsetX...的位置
  3. 當鼠標離開時,解綁鼠標移動事件

實現過程(一)

css 部分html

.decision-box{ position: relative; width: 1500px; height: 600px; border: 1px solid #000; border-radius: 6px; /*margin-left: -40px;*/ } .item{ position: absolute; width: 50px; height: 30px; background: green; border-radius: 6px; text-align: center; line-height: 30px; cursor: pointer; left: 50px } 

html 部分web

<div class="decision-box decision_box"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div> 

js 部分瀏覽器

//鼠標按下,要在移動元素上按下 $(document).on('mousedown','.decision_box .item',function(e){ var ele = $(e.target); $(document).on('mousemove','.decision_box',function(e){ //移動鼠標時改變元素位置 var x = e.offsetX, y = e.offsetY; ele.css({ left:x - 25 + 'px', top:y - 15 + 'px' }); e.stopPropagation(); }); e.stopPropagation(); }); //鼠標放開 $(document).on('mouseup',function(){ //解除鼠標移動事件 $(document).off('mousemove'); }); 

這時,發生了錯誤,元素一閃一閃的,位置不是一直跟着鼠標,在mousemove觸發函數裏打印一下位置,發現位置不一直是鼠標位置。原來是應爲鼠標位置offsetX的緣由。bash

關於鼠標位置

  • clientX 相對於但是窗口的距離
  • offsetX 相對於e.target元素的位置
  • pageX 相對於文檔的左邊緣
  • screenX 相對於屏幕的位置

原來offsetX是相對於e.target元素的位置。加入被拖拽元素寬高100px,當我點擊100px,100px時,元素的中心位置變爲100,100;此時offsetX又變爲了50;這時offsetX又變回100;(以上數字只是數字,由於有移動)。如上,就造成了一閃一閃,以後鼠標會超過元素範圍,這時,元素位置就在鼠標相對於自己和鼠標相對於父盒子之間切換。函數

那麼怎麼解決這個問題呢?個人思路是:spa

  • 使用其它鼠標位置,當點擊元素時獲取位置做爲初始位置
  • 當移動時獲取位置並求出相對位移,這個相對於位移也就是元素要移動的距離。

實現過程(二)

js 部分code

//鼠標按下,要在移動元素上按下 $(document).on('mousedown','.decision_box .item',function(e){ console.log(parseInt($(e.target).css('left'))) var ele = $(e.target); var initX = e.clientX, initY = e.clientY, itemX = parseInt(ele.css('left')); itemY = parseInt(ele.css('top')); $(document).on('mousemove','.decision_box',function(e){ //移動鼠標時改變元素位置 var curX = e.clientX, curY = e.clientY; ele.css({ left:itemX + (curX - initX) + 'px', top:itemY + (curY - initY) + 'px' }); e.stopPropagation(); }); e.stopPropagation(); }); //鼠標放開 $(document).on('mouseup',function(){ //解除鼠標移動事件 $(document).off('mousemove'); }); 

成功,能夠拖動了,這時又趕上了一個問題,當拖動元素時,有其它文本別選中時,拖拽又出現了bug,這時就要用到下面面這兩個屬性xml

onselectstart = "return false";
onselect = "return false";
  • onselectstart事件不被input和textarea標籤支持,而onselect事件只被input和textarea支持。
  • Firefox/Opera不支持onselectstart事件Firefox中能夠使用CSS "-moz-user-select:none"屬性來禁止文本選定
  • webkit瀏覽器能夠使用「-khtml-user-select」,固然也能夠使用onselectstart事件來阻止用戶選定元素內文本,以下
<div onselectstart="return false">accc</div> 

這個屬性意思就是不讓文本被選中。要作的就是當點擊元素時,上這個屬性,當放開鼠標時去掉這個屬性(改爲return true);htm

最後代碼

//鼠標按下,要在移動元素上按下 $(document).on('mousedown','.decision_box .item',function(e){ $('body').attr('onselectstart','return false'); console.log(parseInt($(e.target).css('left'))) var ele = $(e.target); var initX = e.clientX, initY = e.clientY, itemX = parseInt(ele.css('left')); itemY = parseInt(ele.css('top')); $(document).on('mousemove','.decision_box',function(e){ //移動鼠標時改變元素位置 var curX = e.clientX, curY = e.clientY; ele.css({ left:itemX + (curX - initX) + 'px', top:itemY + (curY - initY) + 'px' }); e.stopPropagation(); }); e.stopPropagation(); }); //鼠標放開 $(document).on('mouseup',function(){ $('body').attr('onselectstart','return true'); //解除鼠標移動事件 $(document).off('mousemove'); }); 

這時,選中文本後再進行拖拽還有問題,(也可不解決)我暫時不知道;還有碰撞檢測什麼的也沒加。待續......

 

https://www.jianshu.com/p/bd6e4f6122cf

相關文章
相關標籤/搜索