JS代碼需要常寫,不然容易生疏,最近雖然一直在看JS的原型,行為委托等知識點,但是動手寫代碼的量略有減少。周末在家,寫了一個拖拽組件,與大家分享。
首先,看一下拖拽的原理。

被拖拽元素位置的變化,left值的變化其實就是鼠標位置水平方向的變化值,e.clientX - 鼠標左鍵按下時e.clientX。
top值的變化其實就是鼠標位置豎直方向的變化值,e.clientY - 鼠標左鍵按下時e.clientY。
另外就是設置拖拽的范圍,上下左右不得超過父元素所在的區域。
~~~
function Drag (config){
this.moveTarget = document.getElementById(config.id);
if(config.parentId){
this.targetParent = document.getElementById(config.parentId);
this.max_left = this.targetParent.clientWidth - this.moveTarget.offsetWidth;
this.max_top = this.targetParent.clientHeight - this.moveTarget.offsetHeight;
}else{
console.log(document.documentElement.clientHeight + "||" + this.moveTarget.offsetHeight)
this.max_left = document.documentElement.clientWidth - this.moveTarget.offsetWidth -
parseInt(this.getStyle(document.body, "border-width"));
this.max_top = document.documentElement.clientHeight - this.moveTarget.offsetHeight-
parseInt(this.getStyle(document.body, "border-width"));
}
this.lock = true;
}
Drag.prototype.getStyle = function(element, attr){
if(element.currentStyle){
return element.currentStyle[attr];
}else{
return window.getComputedStyle(element,null).getPropertyValue(attr)
}
}
Drag.prototype.moDown = function(e){
e = e || window.event;
this.clientX = e.clientX;
this.clientY = e.clientY;
//鼠標按下時,drag的left值,top值(寫在style中或者是css中)
this.startLeft = parseInt(this.moveTarget.style.left || this.getStyle(this.moveTarget, "left"));
this.startTop = parseInt(this.moveTarget.style.top || this.getStyle(this.moveTarget, "top"));
//鼠標按下時,鼠標的clientX值,clientY值
this.startClientX = e.clientX;
this.startClientY = e.clientY;
this.lock = false;
};
Drag.prototype.moMove = function(e){
e = e || window.event;
if(e.which != 1){
this.lock = true;
}
if(!this.lock){
var realLeft = this.startLeft + e.clientX - this.startClientX;//實際的移動范圍
var realTop = this.startTop + e.clientY - this.startClientY;
//rightLeft , rightTop; //left, top 取值(在可移動范圍內)
var rightLeft = realLeft > this.max_left ? this.max_left : ( realLeft > 0 ? realLeft : 0 );
var rightTop = realTop > this.max_top ? this.max_top : ( realTop > 0 ? realTop : 0 );
this.moveTarget.style.left = rightLeft + "px";
this.moveTarget.style.top = rightTop + "px";
}
};
Drag.prototype.moUp = function(e){
e = e || window.event;
this.lock = true;
};
Drag.prototype.startDrag = function(){
console.log(this)
this.moveTarget.onmousedown = function(e){this.moDown(e)}.bind(this);
this.moveTarget.onmousemove = function(e){this.moMove(e)}.bind(this);
this.moveTarget.onmouseup = function(e){this.moUp(e)}.bind(this);
}
~~~
說明:moDown響應鼠標左鍵按下操作,moMove響應鼠標移動操作,MoUp響應鼠標抬起操作。
在moMove中增加了e.which判斷,e.which ==1 表示鼠標左鍵按下,這是為了解決,鼠標移除可拖拽范圍外,再移回時,無需按下左鍵,被拖拽元素就會跟著動的Bug。
使用說明:
在使用時,被拖拽元素的id是必須參數,父元素的id(即可以拖拽移動的范圍)為可選參數,如果不傳遞父元素的id,則默認使用documentElement為可拖拽的范圍。
如果傳遞父元素,請別忘了將父元素的定位設為position:relative或position:absolute。
在使用時,先引入拖拽插件的js文件。
~~~
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus?">
<meta name="Author" content="劉艷">
<meta name="Keywords" content="關鍵字">
<meta name="Description" content="描述">
<title>Document</title>
<style>
*{
margin:0px;
padding:0px;
}
#content{
width:600px;
height:500px;
position:relative;
border:5px solid green;
}
#drag{
position:absolute;
height:100px;
width:100px;
top:50px;left:0px;
background:pink;
cursor:pointer;
}
</style>
</head>
<body>
<div id = "content">
<div id = "drag" >
</div>
</div>
</body>
</html>
<script src = "url/drag.js"></script>
<script>
window.onload = function(){
var drag = new Drag({id: "drag", parentId: "content"});
drag.startDrag();
}
</script>
~~~
如果您想在整個窗口中拖拽,請不要設置被拖拽元素的父元素的定位,即,使其相對body定位。
如果您需要對body定位,但是又需要設置其父元素的position為非static,那么您可以對本插件進行擴展。
希望本文對您JS的學習能有所幫助。
- 前言
- jQuery輪播圖插件
- JS模擬事件操作
- JS閉包與變量
- JS綁定事件
- HTML5之file控件
- JavaScript的this詞法
- JavaScript的this詞法(二)
- JS this詞法(三)
- JS檢測瀏覽器插件
- JS拖拽組件開發
- number輸入框
- Modernizr.js和yepnode.js
- DOM變化后事件綁定失效
- div和img之間的縫隙問題
- 詳解JavaScript作用域
- bootstrap入門
- 表單驗證(登錄/注冊)
- Bootstrap網格系統
- Bootstrap排版
- Bootstrap創建表單(一)
- Bootstrap表單(二)
- Bootstrap按鈕
- Bootstrap圖片
- Bootstrap字體圖標(glyphicons)
- Bootstrap的aria-label和aria-labelledby
- Bootstrap下拉菜單
- Bootstrap按鈕組
- Bootstrap按鈕菜單
- Bootstrap輸入框組
- Bootstrap導航元素
- Bootstrap導航欄
- sublimeText頻頻崩潰
- JQuery不同版本的差異(checkbox)
- Bootstrap面包屑導航、分頁、標簽、徽章
- Bootstrap警告
- Bootstrap進度條
- 前端的上傳下載
- JS字符串的相關方法
- CSS3選擇器(全)
- CSS3新增文本屬性詳述
- 利用CSS3實現圖片切換特效
- CSS3新增顏色屬性
- CSS3的border-radius屬性詳解
- JS創建對象幾種不同方法詳解
- JS實現繼承的幾種方式詳述(推薦)
- CSS3響應式布局
- JS模塊化開發(requireJS)
- 利用@font-face實現個性化字體
- 前端在html頁面之間傳遞參數的方法
- CSS自動換行、強制不換行、強制斷行、超出顯示省略號
- 如何在Html中引入外部頁面
- reactJS入門
- React組件生命周期
- 使用React實現類似快遞單號查詢效果
- ReactJS組件生命周期詳述
- React 屬性和狀態詳解