淺析JavaScript動(dòng)畫(huà)模擬拖拽原理
模擬拖拽的原理:

x1等于div.offsetLeft
y1等于div.offsetTop
x2等于ev.clientX(ev表示event事件)
y2等于ev.clientY
當(dāng)我們?cè)诜綁K上按下鼠標(biāo)的時(shí)候,x2-x1即可確定。移動(dòng)鼠標(biāo)之后,我們用鼠標(biāo)當(dāng)前的位置即x4、y4減去x2-x1、y2-y1就可以得到方塊現(xiàn)在的位置。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
var oBox = document.getElementById('box');
oBox.onmousedown = function(ev){
// 鼠標(biāo)按下
var ev = ev || event;
// 獲取鼠標(biāo)離div得距離
var mouseBoxleft = ev.clientX - this.offsetLeft;
var mouseBoxTop = ev.clientY - this.offsetTop;
oBox.onmousemove = function(ev){
// 鼠標(biāo)按下左鍵并移動(dòng)
var ev = ev || event;
// 設(shè)置div移動(dòng)時(shí),它的位置
oBox.style.left = ev.clientX - mouseBoxleft + 'px';
oBox.style.top = ev.clientY - mouseBoxleft + 'px';
}
oBox.onmouseup = function(){
// 鼠標(biāo)左鍵抬起
oBox.onmousemove = oBox.onmouseup = null;
}
}
</script>
</body>
</html>
優(yōu)化代碼:
【1】鼠標(biāo)移動(dòng)快的時(shí)候,鼠標(biāo)會(huì)移出方塊,這時(shí)方塊就不會(huì)再跟隨鼠標(biāo)動(dòng)了。
解決辦法:就是將onmousemove和onmouseup加到document對(duì)象上
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
oBox.onmousedown = function(ev){
// 鼠標(biāo)按下
var ev = ev || event;
// 獲取鼠標(biāo)離div得距離
var mouseBoxleft = ev.clientX - this.offsetLeft;
var mouseBoxTop = ev.clientY - this.offsetTop;
document.onmousemove = function(ev){
// 鼠標(biāo)按下左鍵并移動(dòng)
var ev = ev || event;
// 設(shè)置div移動(dòng)時(shí),它的位置
oBox.style.left = ev.clientX - mouseBoxleft + 'px';
oBox.style.top = ev.clientY - mouseBoxleft + 'px';
}
document.onmouseup = function(){
// 鼠標(biāo)左鍵抬起
document.onmousemove = document.onmouseup = null;
}
}
</script>
</body>
</html>
【2】當(dāng)要拖動(dòng)的方塊中有文字時(shí)會(huì)觸發(fā)瀏覽器的默認(rèn)行為
解決辦法:1、使用return false添加到onmousedown事件中阻止瀏覽器的默認(rèn)行為(IE除外)
2、使用全局捕獲(IE)
1、使用return false添加到onmousedown事件中阻止瀏覽器的默認(rèn)行為(IE除外)
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div id="box">模擬拖拽</div>
<script>
var oBox = document.getElementById('box');
oBox.onmousedown = function(ev){
// 鼠標(biāo)按下
var ev = ev || event;
// 獲取鼠標(biāo)離div得距離
var mouseBoxleft = ev.clientX - this.offsetLeft;
var mouseBoxTop = ev.clientY - this.offsetTop;
document.onmousemove = function(ev){
// 鼠標(biāo)按下左鍵并移動(dòng)
var ev = ev || event;
// 設(shè)置div移動(dòng)時(shí),它的位置
oBox.style.left = ev.clientX - mouseBoxleft + 'px';
oBox.style.top = ev.clientY - mouseBoxleft + 'px';
}
document.onmouseup = function(){
// 鼠標(biāo)左鍵抬起
document.onmousemove = document.onmouseup = null;
}
// 阻止默認(rèn)行為
return false;
}
</script>
</body>
</html>
2、使用全局捕獲(IE)
全局捕獲:當(dāng)我們給一個(gè)元素這只全局捕獲后,改元素會(huì)監(jiān)聽(tīng)后續(xù)發(fā)生的所有事件,當(dāng)有事件發(fā)生的時(shí)候就會(huì)觸發(fā)改元素的事件
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input type="button" id="button1" value="彈出1" />
<input type="button" id="button2" value="彈出2" />
<script type="text/javascript">
window.onload = function(){
var Btn1 = document.getElementById('button1');
var Btn2 = document.getElementById('button2');
Btn1.setCapture();
Btn1.onclick = function(){
alert(1);
}
Btn2.onclick = function(){
alert(2);
}
}
</script>
</body>
</html>
給Btn1設(shè)置了全局捕獲之后,即使我們點(diǎn)擊了Btn2還是會(huì)觸發(fā)Btn1的點(diǎn)擊事件
在模擬拖拽中,給要拖拽的方塊onmousedown添加全局捕獲然后再onmouseup中取消全局捕獲
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box">模擬拖拽</div>
<script>
var oBox = document.getElementById('box');
oBox.onmousedown = function(ev){
// 鼠標(biāo)按下
var ev = ev || event;
// 獲取鼠標(biāo)離div得距離
var mouseBoxleft = ev.clientX - this.offsetLeft;
var mouseBoxTop = ev.clientY - this.offsetTop;
// IE瀏覽器,全局捕獲
if(oBox.setCapture){
oBox.setCapture();
}
document.onmousemove = function(ev){
// 鼠標(biāo)按下左鍵并移動(dòng)
var ev = ev || event;
// 設(shè)置div移動(dòng)時(shí),它的位置
oBox.style.left = ev.clientX - mouseBoxleft + 'px';
oBox.style.top = ev.clientY - mouseBoxleft + 'px';
}
document.onmouseup = function(){
// 鼠標(biāo)左鍵抬起
document.onmousemove = document.onmouseup = null;
//IE下,釋放全局捕獲 releaseCapture();
if ( oBox.releaseCapture ) {
oBox.releaseCapture();
}
}
// 阻止默認(rèn)行為
return false;
}
</script>
</body>
</html>
【3】封裝模擬拖拽函數(shù)
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="box">模擬拖拽</div>
<script>
var oBox = document.getElementById('box');
drag(oBox);
function drag(obj){
obj.onmousedown = function(ev){
// 鼠標(biāo)按下
var ev = ev || event;
// 獲取鼠標(biāo)離div得距離
var mouseBoxleft = ev.clientX - this.offsetLeft;
var mouseBoxTop = ev.clientY - this.offsetTop;
// IE瀏覽器,全局捕獲
if(obj.setCapture){
obj.setCapture();
}
document.onmousemove = function(ev){
// 鼠標(biāo)按下左鍵并移動(dòng)
var ev = ev || event;
// 設(shè)置div移動(dòng)時(shí),它的位置
obj.style.left = ev.clientX - mouseBoxleft + 'px';
obj.style.top = ev.clientY - mouseBoxleft + 'px';
}
document.onmouseup = function(){
// 鼠標(biāo)左鍵抬起
document.onmousemove = document.onmouseup = null;
//IE下,釋放全局捕獲 releaseCapture();
if ( obj.releaseCapture ) {
obj.releaseCapture();
}
}
// 阻止默認(rèn)行為
return false;
}
}
</script>
</body>
</html>
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- javascript 流暢動(dòng)畫(huà)實(shí)現(xiàn)原理
- Javascript動(dòng)畫(huà)的實(shí)現(xiàn)原理淺析
- JS前端可視化canvas動(dòng)畫(huà)原理及其推導(dǎo)實(shí)現(xiàn)
- 九種原生js動(dòng)畫(huà)效果
- JS動(dòng)畫(huà)效果代碼3
- JS實(shí)現(xiàn)圖片旋轉(zhuǎn)動(dòng)畫(huà)效果封裝與使用示例
- JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)畫(huà)彈出層效果
- JavaScript動(dòng)畫(huà)原理之如何使用js進(jìn)行動(dòng)畫(huà)效果的實(shí)現(xiàn)
相關(guān)文章
關(guān)于JS中setTimeout()無(wú)法調(diào)用帶參函數(shù)問(wèn)題的解決方法
這篇文章主要介紹了關(guān)于JS中setTimeout()無(wú)法調(diào)用帶參函數(shù)問(wèn)題的解決方法,提供了2種解決方法供大家對(duì)比參考,需要的朋友可以參考下2016-06-06
詳解JavaScript正則表達(dá)式之分組匹配及反向引用
這篇文章主要介紹了詳解JavaScript正則表達(dá)式之分組匹配及反向引用 的相關(guān)資料,需要的朋友可以參考下2016-03-03
Javascript中匿名函數(shù)的調(diào)用與寫(xiě)法實(shí)例詳解(多種)
js中定義函數(shù)的方式有很多種,函數(shù)直接量就是其中一種,下面通過(guò)本文給大家介紹匿名函數(shù)是如何調(diào)用的及匿名函數(shù)的n中寫(xiě)法,對(duì)js匿名函數(shù)調(diào)用,js匿名函數(shù)寫(xiě)法相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01
javascript Array對(duì)象使用小結(jié)
數(shù)組是一段線性分配的內(nèi)存,它通過(guò)整數(shù)去計(jì)算偏移并訪問(wèn)其中的元素。數(shù)組是很快的數(shù)據(jù)結(jié)構(gòu),但不幸的是,Javascript并沒(méi)有像這種數(shù)組一樣的數(shù)據(jù)結(jié)構(gòu)。2009-12-12
原生JS實(shí)現(xiàn)簡(jiǎn)單的倒計(jì)時(shí)功能示例
這篇文章主要介紹了原生JS實(shí)現(xiàn)簡(jiǎn)單的倒計(jì)時(shí)功能,涉及javascript基于定時(shí)器的日期時(shí)間運(yùn)算與頁(yè)面元素屬性動(dòng)態(tài)修改相關(guān)操作技巧,需要的朋友可以參考下2018-08-08
微信小程序跨頁(yè)面數(shù)據(jù)傳遞事件響應(yīng)實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了微信小程序跨頁(yè)面數(shù)據(jù)傳遞事件響應(yīng)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
JS清除字符串中重復(fù)值的實(shí)現(xiàn)方法
這篇文章主要介紹了JS清除字符串中重復(fù)值的實(shí)現(xiàn)方法,涉及javascript數(shù)組與字符串的遍歷、比較及數(shù)學(xué)運(yùn)算相關(guān)技巧,需要的朋友可以參考下2016-08-08

