欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript動(dòng)畫(huà)之模擬拖拽效果篇

 更新時(shí)間:2016年09月26日 15:39:32   作者:小火柴的藍(lán)色理想  
其實(shí)javascript本身是具有原生拖放功能的,但是由于兼容性問(wèn)題,以及功能實(shí)現(xiàn)的方式,用的不是很廣泛。javascript動(dòng)畫(huà)廣泛使用的還是模擬拖拽。本文將詳細(xì)介紹javascript的模擬拖拽,有需要的可以參考借鑒。

先看看實(shí)現(xiàn)效果圖, 模擬拖拽最終效果和在桌面上移動(dòng)文件夾的效果類似

原理介紹

鼠標(biāo)按下時(shí),拖拽開(kāi)始。鼠標(biāo)移動(dòng)時(shí),被拖拽元素跟著鼠標(biāo)一起移動(dòng)。鼠標(biāo)抬起時(shí),拖拽結(jié)束

所以,拖拽的重點(diǎn)是確定被拖拽元素是如何移動(dòng)的

假設(shè),鼠標(biāo)按下時(shí),鼠標(biāo)對(duì)象的clientX和clientY分別為x1和x2。元素距離視口左上角x軸和y軸分別為x0和y0

鼠標(biāo)移動(dòng)的某一時(shí)刻,clientX和clientY分別為x2和y2

所以,元素移動(dòng)的x軸和y軸距離分別為x2-x1和y2-y1

元素移動(dòng)后,元素距離視口左上角x軸和y軸的位置分別為

 X = x0 + (x2-x1)
 Y = y0 + (y2-y1)

代碼實(shí)現(xiàn)

  將上面的原理用代碼實(shí)現(xiàn)如下

  鼠標(biāo)按下時(shí),初始態(tài)的x0和y0分別用offsetLeftoffsetTop表示

  鼠標(biāo)移動(dòng)時(shí),瞬時(shí)態(tài)的x和y分別賦值為定位后元素的left和top

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;"></div>
<script>
test.onmousedown = function(e){
 e = e || event;
 //獲取元素距離定位父級(jí)的x軸及y軸距離
 var x0 = this.offsetLeft;
 var y0 = this.offsetTop;
 //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
 var x1 = e.clientX;
 var y1 = e.clientY;

 test.onmousemove = function(e){
  e = e || event;
  //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
  x2 = e.clientX;
  y2 = e.clientY; 
  //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離
  var X = x0 + (x2 - x1);
  var Y = y0 + (y2 - y1);
  //將X和Y的值賦給left和top,使元素移動(dòng)到相應(yīng)位置
  test.style.left = X + 'px';
  test.style.top = Y + 'px';
 }

 test.onmouseup = function(e){
  //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可
  test.onmousemove = null;
 }
}
</script>

代碼優(yōu)化

  使用上面的代碼時(shí),會(huì)出現(xiàn)一個(gè)問(wèn)題。當(dāng)鼠標(biāo)拖動(dòng)的太快,比onmousemove事件的觸發(fā)間隔還要快時(shí),鼠標(biāo)就會(huì)從元素上離開(kāi)。這樣就停止了元素的拖拽過(guò)程

  此時(shí),如果把mousemovemouseup事件都加在document上時(shí),即可解決

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;"></div>
<script>
test.onmousedown = function(e){
 e = e || event;
 //獲取元素距離定位父級(jí)的x軸及y軸距離
 var x0 = this.offsetLeft;
 var y0 = this.offsetTop;
 //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
 var x1 = e.clientX;
 var y1 = e.clientY;

 document.onmousemove = function(e){
  e = e || event;
  //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
  x2 = e.clientX;
  y2 = e.clientY; 
  //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離
  var X = x0 + (x2 - x1);
  var Y = y0 + (y2 - y1);
  //將X和Y的值賦給left和top,使元素移動(dòng)到相應(yīng)位置
  test.style.left = X + 'px';
  test.style.top = Y + 'px';
 }

 document.onmouseup = function(e){
  //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可
  document.onmousemove = null;
 }
}
</script>

拖拽沖突

  由于文字和圖片默認(rèn)支持原生拖放,如果將原生拖放和模擬拖拽摻雜在一起,將造成與預(yù)想效果不符的情況

  如果拖放的元素內(nèi)容存在文字,且文字被選中會(huì)觸發(fā)文字的原生拖放效果

  在文字上面雙擊鼠標(biāo),即可選中文字,再移動(dòng)鼠標(biāo)時(shí),會(huì)觸發(fā)文字的原生拖放效果,如下所示

  只要在onmousedown事件阻止瀏覽器的默認(rèn)行為即可

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測(cè)試文字</div>
<script>
test.onmousedown = function(e){
 e = e || event;
 //獲取元素距離定位父級(jí)的x軸及y軸距離
 var x0 = this.offsetLeft;
 var y0 = this.offsetTop;
 //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
 var x1 = e.clientX;
 var y1 = e.clientY;

 document.onmousemove = function(e){
  e = e || event;
  //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
  x2 = e.clientX;
  y2 = e.clientY; 
  //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離
  var X = x0 + (x2 - x1);
  var Y = y0 + (y2 - y1);
  //將X和Y的值賦給left和top,使元素移動(dòng)到相應(yīng)位置
  test.style.left = X + 'px';
  test.style.top = Y + 'px';
 }

 document.onmouseup = function(e){
  //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可
  document.onmousemove = null;
 }
 //阻止默認(rèn)行為
 return false;
}
</script>

IE兼容

  以上代碼在IE8-瀏覽器中仍然無(wú)法阻止默認(rèn)行為。此時(shí),為了實(shí)現(xiàn)IE兼容,需要使用全局捕獲setCapture()和釋放捕獲releaseCapture()

  首先,先看一下全局捕獲的效果

  下面代碼中,開(kāi)啟全局捕獲之后,頁(yè)面中的所有點(diǎn)擊效果,都相當(dāng)于針對(duì)按鈕一的點(diǎn)擊效果。釋放捕獲后,效果消失

  [注意]IE瀏覽器完全支持全局捕獲;chrome不支持,使用全局捕獲會(huì)報(bào)錯(cuò);firefox不報(bào)錯(cuò),但靜默失敗

<button id="btn1">按鈕一</button>
<button id="btn2">開(kāi)啟按鈕一的全局捕獲</button>
<script>
btn1.onclick = function(){
 alert(1);
}
btn2.onclick = function(){
 if(btn1.setCapture){
  if(btn2.innerHTML.charAt(0) == '開(kāi)'){
   btn1.setCapture();
   btn2.innerHTML = '關(guān)閉按鈕一的全局捕獲';
  }else{
   btn1.releaseCapture();
   btn2.innerHTML = '開(kāi)啟按鈕一的全局捕獲'; 
  }
 }
}
</script>

  通過(guò)在IE瀏覽器設(shè)置全局捕獲來(lái)達(dá)到取消文字原生拖放的默認(rèn)行為

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測(cè)試文字</div>
<script>
test.onmousedown = function(e){
 e = e || event;
 //獲取元素距離定位父級(jí)的x軸及y軸距離
 var x0 = this.offsetLeft;
 var y0 = this.offsetTop;
 //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
 var x1 = e.clientX;
 var y1 = e.clientY;

 document.onmousemove = function(e){
  e = e || event;
  //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離
  x2 = e.clientX;
  y2 = e.clientY; 
  //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離
  var X = x0 + (x2 - x1);
  var Y = y0 + (y2 - y1);
  //將X和Y的值賦給left和top,使元素移動(dòng)到相應(yīng)位置
  test.style.left = X + 'px';
  test.style.top = Y + 'px';
 }

 document.onmouseup = function(e){
  //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可
  document.onmousemove = null;
  //釋放全局捕獲
  if(test.releaseCapture){
   test.releaseCapture();
  }
 }
 //阻止默認(rèn)行為
 return false;
 //IE8-瀏覽器阻止默認(rèn)行為
 if(test.setCapture){
  test.setCapture();
 }
}
</script>

總結(jié)

以上就是Javascript模擬拖拽的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

最新評(píng)論