IT技(ji)術(shu)互動交(jiao)流平台

乐彩网官网

作者︰風沙渡  發布日期︰2020-02-18 12:11:08

一、實現(xian)的效果(guo)是在限(xian)制範(fan)圍內拖(tuo)拽div+吸附+事件捕獲。

這里(li)需要(yao)理解(jie)的是事件捕獲,這個事件捕獲也(ye)是為了兼容div在拖(tuo)拽過程中(zhong),文(wen)本不被選中(zhong)這個問題。

如(ru)此良辰(chen)美(mei)景,拖(tuo)拽也(ye)可以很灑脫哈。先看看圖,

二、一步(bu)步(bu)的實現(xian)這個拖(tuo)拽過程的幾個要(yao)求

(一)拖(tuo)拽起來

里(li)面的邊框是表示頁(ye)面哦(ou)(我們的屏幕所能看到的東東)。

獲取移動距離的思路︰

記錄鼠標按下和鼠標抬起兩次的坐標,然後相減,再加(jia)上div跟邊緣之間(jian)的間(jian)距。就(jiu)得到移動距離。

之前我也(ye)在這里(li)困惑了,不明白為什麼還要(yao)再加(jia)上offsetLeft。原因(yin)就(jiu)是clientX獲取到的是數(shu)值是不加(jia)上div跟邊緣的距離,不是marin,也(ye)不是padding,而是瀏覽器渲染的問題。

[下面是我自己的理解(jie)︰

終(zhong)于明白這個移動距離是如(ru)何計算(suan)出來的mo)/strong>

將式子化(hua)簡之後,得到的就(jiu)是移動後的Div  clientX-移動前clientX,然後再加(jia)上offsetLeft,因(yin)為這個clientX是沒(mei)有把邊緣dao)撲suan)下去,為了獲取準確(que)的數(shu)值,要(yao)把瀏覽器默認的邊緣dao)撲suan)下去。

如(ru)圖所以︰鼠標移動過的距離就(jiu)是我用(yong)紅色畫出部分再加(jia)上div跟邊緣之間(jian)的offsetLeft(X軸方向)和offsetTop(Y軸方向)。

如(ru)果(guo)上面式子不好mei)斫jie),就(jiu)把他化(hua)簡之後來看,就(jiu)明白了。]

距離獲取完成。

現(xian)在就(jiu)可以通過鼠標的三個事件onmousedown、onmousemove、onmouseup來拖(tuo)拽鼠標。當鼠標移動時,就(jiu)不斷地更改div的left和top屬性

oDiv2.style.left = l +'px';Div2.style.top = t +'px';

 最(zui)後,當鼠標抬起時,要(yao)釋(shi)放onmousedown和onmousemove事件。

this.onmousedown = null;this.onmousemove = null;

(二)邊緣吸附

邊緣吸附的原理so easy。

給一個判斷條件,當div運動到距離上下左右邊緣的距離小于某(mou)一個值時,這時就(jiu)把left和top的值更改為邊緣的值。這樣div就(jiu)貼到邊緣上去。

   var l1= oDiv1.offsetWidth - oDiv2.offsetWidth; //限(xian)制小div在大(da)div中(zhong)拖(tuo)拽,計算(suan)能拖(tuo)拽的max距離  var t1 = oDiv1.offsetHeight - oDiv2.offsetHeight;  if(l > l1-50)  {   l = l1;  }  if(l < 50)  {   l = 0;  }  if(t > t1-50)  {   t = t1;  }  if(t < 50)  {   t = 0;  }   

(三)拖(tuo)拽過程不被文(wen)字選中(zhong)

div在拖(tuo)拽過程中(zhong),在div中(zhong)的文(wen)本文(wen)字總是會被選中(zhong),為了si)jie)決這個問題,要(yao)使用(yong)一個叫(jiao)做事件捕獲的知(zhi)識。

1、先理解(jie)一下什麼是事件捕獲

是跟事件冒泡相反的一種模(mo)型。事件捕獲的是最(zui)後獲得事件的是最(zui)小的子元(yuan)素。事件冒泡最(zui)後獲得事件的是父元(yuan)素。

之所以在拖(tuo)拽過程中(zhong),div中(zhong)的文(wen)字會被選中(zhong)就(jiu)是因(yin)為我沒(mei)有處理好事件冒泡的問題。要(yao)解(jie)決這個問題,解(jie)鈴還須系鈴人,就(jiu)把事件冒泡的問題處理好久(jiu)ok。

       if(oDiv2.setCapture)    //IE  {  document.onmousemove = moveFn;  document.onmouseup = upFn;  oDiv2.setCapture();    //事件捕獲後,所有事件都ji) zhong)到這個div  return false;    //FF、Chrome、IE9  }else      //FF、chrome  {  document.onmousemove = moveFn;  //!!!!根(gen)源所在,在優化(hua)版1中(zhong),設置為oDiv2.onmousemove時拖(tuo)拽一次後無法再拖(tuo)拽  document.onmouseup = upFn;  }

記得事件捕獲後,當鼠標抬起時,也(ye)好釋(shi)放

oDiv2.releaseCapture();

三、div拖(tuo)拽的詳細(xi)代碼


<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>限(xian)制範(fan)圍內拖(tuo)拽</title> <style> * { margin: 0; padding: 0; } #div1 { width: 500px; height: 500px; background: #CCC; position: relative; } #div2 { width: 100px; height: 100px; background: green; position: absolute; left: 0; top: 0; } </style> <script> window.onload = function() { var oDiv1 = document.getElementById('div1'); var oDiv2 = document.getElementById('div2');  var disX,disY; /*--------------開始(shi)拖(tuo)拽div2-----------------*/ oDiv2.onmousedown = function(evt)   //oDiv2.onmousedown表示按下這個對象,, document.onmouseup整個文(wen)檔對象(這里(li)把div改mou)ocument是防止弄丟(ding)div) {  var oEvent = evt window.event;  //evt兼容FF/Chrome  disX = oEvent.clientX - oDiv2.offsetLeft; //-oDiv2.offsetLeft的距離是為了減去div與(yu)視(shi)口(kou)邊框的距離  disY = oEvent.clientY - oDiv2.offsetTop;  if(oDiv2.setCapture)    //IE  {  document.onmousemove = moveFn;  document.onmouseup = upFn;  oDiv2.setCapture();    //事件捕獲後,所有事件都ji) zhong)到這個div  return false;     //FF、Chrome、IE9  }else      //FF、chrome  {  document.onmousemove = moveFn;  //!!!!根(gen)源所在,在優化(hua)版1中(zhong),設置為oDiv2.onmousemove時拖(tuo)拽一次後無法再拖(tuo)拽  document.onmouseup = upFn;  }  function moveFn(evt)   //把document重(zhong)新(xin)改為div,利用(yong)setCapture事件捕獲,把事件都ji) zhong)在一個物體上  {  var oEvent = evt window.event;  var l = oEvent.clientX - disX;  //計算(suan)鼠標移過的距離  var t = oEvent.clientY - disY;  var l1= oDiv1.offsetWidth - oDiv2.offsetWidth; //限(xian)制小div在大(da)div中(zhong)拖(tuo)拽,計算(suan)能拖(tuo)拽的max距離  var t1 = oDiv1.offsetHeight - oDiv2.offsetHeight;  if(l > l1-50)  {   l = l1;  }  if(l < 50)  {   l = 0;  }  if(t > t1-50)  {   t = t1;  }  if(t < 50)  {   t = 0;  }  oDiv2.style.left = l +'px';  oDiv2.style.top = t +'px';  }  function upFn()  {  this.onmousedown = null;  this.onmousemove = null;    if(oDiv2.releaseCapture)     //如(ru)果(guo)事件捕獲存在,則釋(shi)放事件捕獲  {   oDiv2.releaseCapture();  }  }  return false;      //阻止瀏覽器默認事件 }; }; </script></head><body><div id='div1'>使用(yong)了事件捕獲後,現(xian)在拖(tuo)拽div中(zhong)的問題可不應該被選中(zhong)了哦(ou)</div><div id='div2'>helloworld helloworld</div></body></html>

乐彩网官网

Tag標簽(qian)︰範(fan)圍  事件  
  • 乐彩网官网

About IT165 - 亿博平台官网廣告服務(wu) - 大发欢乐生肖官网隱私(si)聲明 - 版權(quan)申明 - 免責條款(kuan) - 網站地圖 - 網友投稿 - 聯(lian)系方式
本站內容來自于互聯(lian)網,僅供用(yong)于網絡技(ji)術(shu)學習,學習中(zhong)請遵(zun)循相關法律法規
乐彩网官网 | 下一页