JavaScript實(shí)現(xiàn)div的鼠標(biāo)拖拽效果
本文實(shí)例為大家分享了JavaScript實(shí)現(xiàn)div鼠標(biāo)拖拽效果的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)原理鼠標(biāo)按下時(shí)根據(jù)onmousemove事件來動(dòng)態(tài)獲取鼠標(biāo)坐標(biāo)位置以此來更新div的位置,實(shí)現(xiàn)的前提時(shí)div要有一個(gè)定位效果,不然的話是移動(dòng)不了它的。
HTML
<div class="box"></div>
CSS樣式
.box { position: absolute; width: 200px; height: 200px; background: red; }
首先先分析一下需求,這個(gè)需求就是點(diǎn)擊時(shí)鼠標(biāo)按下你才能移動(dòng)并改變div在頁面中的位置。鼠標(biāo)松開你就不能在移動(dòng)了。所以這里鼠標(biāo)的狀態(tài)有三個(gè),分別是點(diǎn)擊時(shí)鼠標(biāo)按下(mousedown事件)、移動(dòng)時(shí)(mousemove事件)、松開時(shí)(mouseup事件)
所以js部分有三個(gè)事件。
JS部分
var box = document.getElementsByClassName("box")[0];//獲取元素 var x, y;//存儲div的坐標(biāo) var isDrop = false;//移動(dòng)狀態(tài)的判斷鼠標(biāo)按下才能移動(dòng)
鼠標(biāo)按下時(shí)
box.onmousedown = function(e) { var e = e || window.event;//要用event這個(gè)對象來獲取鼠標(biāo)的位置 x = e.clientX - box.offsetLeft; y = e.clientY - box.offsetTop; isDrop = true;//設(shè)為true表示可以移動(dòng) }
e.clientX鼠標(biāo)x軸的位置,e.clientY鼠標(biāo)Y軸的位置,box.offsetLeft獲取div距離左邊的距離,box.offsetTop獲取div距離上邊的距離。
如下圖所示 e.clientX - box.offsetLeft我們可以得到坐標(biāo)點(diǎn)x與 box.offsetLeft之間的偏差值,我們要再用坐標(biāo)點(diǎn)x減去這個(gè)偏差值才是div真實(shí)相對于左邊移動(dòng)的距離,e.clientY - box.offsetTop同理得到的是距離上邊偏移的距離。
鼠標(biāo)移動(dòng)時(shí)
為了防止鼠標(biāo)移動(dòng)過快事件無法正確處理所以事件綁定到document上
document.onmousemove = function(e) { //是否為可移動(dòng)狀態(tài) if(isDrop) { var e = e || window.event; var moveX = e.clientX - x;//得到距離左邊移動(dòng)距離 var moveY = e.clientY - y;//得到距離上邊移動(dòng)距離 box.style.left = moveX + "px"; box.style.top = moveY + "px"; }else{ return ; } }
e.clientX - x 鼠標(biāo)點(diǎn)坐標(biāo)減去偏差得到div距離左邊的距離,e.clientY - y 鼠標(biāo)點(diǎn)坐標(biāo)減去偏差得到div距離上邊的距離。給div的left,top重新賦值
鼠標(biāo)松開時(shí)
為了放置鼠標(biāo)移動(dòng)過快時(shí)間無法正確處理所以事件綁定到document上
document.onmouseup = function() { isDrop = false;//設(shè)置為false不可移動(dòng) }
現(xiàn)在div已經(jīng)可以拖拽了,目前還需要添加一個(gè)范圍限定,不然div會拖到頁面外面去,這樣不行的所以得添加范圍限定。div最大移動(dòng)寬度為頁面寬減去div的寬,最小為零,最大高為頁面高減去div的高,最小為零。所以范圍限定要這樣寫
document.onmousemove = function(e) { var e = e || window.event; if(is) { var moveX = e.clientX - x; var moveY = e.clientY - y; var maxX = document.documentElement.clientWidth - box.offsetWidth;//X軸可移動(dòng)最大距離 var maxY = document.documentElement.clientHeight - box.offsetHeight;//Y軸可移動(dòng)最大距離 //范圍限定 最小時(shí)取最大 最大時(shí)取最小 if(moveX < 0) { moveX=0 }else if(moveX>maxX){ moveX=maxX; } if(moveY < 0) { moveY=0; }else if(moveY>maxY){ moveY=maxY; } box.style.left = moveX + "px"; box.style.top = moveY + "px"; } else { return; } }
這樣效果就完美實(shí)現(xiàn)了,但是范圍限定我們還可以這樣做。
可以這樣表示范圍限定
//范圍限定 最小取最大 最大取最小 if(moveX < 0) { moveX= Math.max(0,moveX)//0 }else if(moveX>maxX){ moveX=Math.min(moveX,maxX);//maxX } if(moveY < 0) { moveY= Math.max(0,moveY) //0 }else if(moveY>maxY){ moveY=Math.min(moveY,maxY); //maxY }
所以我們可以這樣寫
moveX=Math.min(maxX, Math.max(0,moveX)); moveY=Math.min(maxY, Math.max(0,moveY));
然后完整代碼
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> .box { position: absolute; width: 200px; height: 200px; background: red; } </style> </head> <body> <div class="box"></div> <script> var box = document.getElementsByClassName("box")[0]; //獲取元素 var x, y; //鼠標(biāo)相對與div左邊,上邊的偏移 var isDrop = false; //移動(dòng)狀態(tài)的判斷鼠標(biāo)按下才能移動(dòng) box.onmousedown = function(e) { var e = e || window.event; //要用event這個(gè)對象來獲取鼠標(biāo)的位置 x = e.clientX - box.offsetLeft; y = e.clientY - box.offsetTop; isDrop = true; //設(shè)為true表示可以移動(dòng) } document.onmousemove = function(e) { //是否為可移動(dòng)狀態(tài) if(isDrop) { var e = e || window.event; var moveX = e.clientX - x; //得到距離左邊移動(dòng)距離 var moveY = e.clientY - y; //得到距離上邊移動(dòng)距離 //可移動(dòng)最大距離 var maxX = document.documentElement.clientWidth - box.offsetWidth; var maxY = document.documentElement.clientHeight - box.offsetHeight; //范圍限定 當(dāng)移動(dòng)的距離最小時(shí)取最大 移動(dòng)的距離最大時(shí)取最小 //范圍限定方法一 /*if(moveX < 0) { moveX = 0 } else if(moveX > maxX) { moveX = maxX; } if(moveY < 0) { moveY = 0; } else if(moveY > maxY) { moveY = maxY; } */ //范圍限定方法二 moveX=Math.min(maxX, Math.max(0,moveX)); moveY=Math.min(maxY, Math.max(0,moveY)); box.style.left = moveX + "px"; box.style.top = moveY + "px"; } else { return; } } document.onmouseup = function() { isDrop = false; //設(shè)置為false不可移動(dòng) } </script> </body> </html>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
深入理解javascript函數(shù)參數(shù)與閉包
函數(shù)是javascript的一等對象,想要學(xué)好javascript,就必須深刻理解函數(shù)。本文對javascript函數(shù)參數(shù)與閉包進(jìn)行詳細(xì)分析介紹。需要的朋友一起來看下吧2016-12-12JavaScript基于Dom操作實(shí)現(xiàn)查找、修改HTML元素的內(nèi)容及屬性的方法
這篇文章主要介紹了JavaScript基于Dom操作實(shí)現(xiàn)查找、修改HTML元素的內(nèi)容及屬性的方法,涉及javascript dom模型及事件響應(yīng)相關(guān)操作技巧,需要的朋友可以參考下2017-01-01仿163填寫郵件地址自動(dòng)顯示下拉(無優(yōu)化)
本框內(nèi)填個(gè)1,這些值都寫在隱藏域了。代碼里可以看到,用戶輸入包含在里面的時(shí)候,可以按ENTER鍵選中.2008-11-11上傳文件返回的json數(shù)據(jù)會被提示下載問題解決方案
這篇文章主要介紹了項(xiàng)目中python+js實(shí)現(xiàn)的上傳文件返回的json數(shù)據(jù)會被提示下載問題解決方案,需要的朋友可以參考下2014-12-1220個(gè)你不得不知道的JS async/await實(shí)用技巧
JavaScript的async和await關(guān)鍵詞是現(xiàn)代JavaScript異步編程的核心,它們讓異步代碼看起來和同步代碼幾乎一樣,使得異步編程變得更加直觀和易于管理,本文介紹20個(gè)關(guān)于async/await的實(shí)用技巧,將大大提升編程效率和代碼的清晰度,需要的朋友可以參考下2023-12-12es6中的import導(dǎo)入模塊 和 export導(dǎo)出模塊詳解
require 是 CommonJS 模塊系統(tǒng)中用于導(dǎo)入模塊的關(guān)鍵字,采用同步加載方式;而 import 和 export 是 ES6 模塊系統(tǒng)中用于導(dǎo)入和導(dǎo)出模塊的關(guān)鍵字,采用靜態(tài)加載方式,并且支持異步加載,這篇文章主要介紹了es6中的import導(dǎo)入模塊 和 export導(dǎo)出模塊,需要的朋友可以參考下2023-11-11