您的位置:首页 > Web前端 > JavaScript

详解原生JavaScript实现div拖拽功能

2015-04-24 17:05 936 查看
div拖拽是使用JavaScript操作HTML元素最基本的一个功能,在很多现有JavaScript库中都实现了这一功能,例如jQuery UI中可以很方便的实现各种拖拽功能,但是在实际操作中尤其是找工作笔试或者面试中,通常要求使用原生JavaScript来实现拖拽功能,所以熟悉div拖拽的原生实现方法很有必要。

通常关于拖拽功能的描述指的是鼠标点击到某元素之后滑动鼠标,该元素会随着鼠标一起滑动,然后要求该元素不得超出父元素的边界。本文所描述即实现该功能。如图,每一个div都可以进行拖拽,但是不可以超出其父元素的边界。


原生实现拖拽功能需要三个鼠标事件函数:onmousedown,onmousemove,onmouseup。每一个div首先绑定onmousedown事件,在函数中记录下鼠标点的坐标,然后再函数内继续绑定onmousemove和onmouseup事件,在onmousemove中实现移动,onmouseup中实现解绑定。具体与拖拽相关的变量如图。



其中变量说明如下:e.clientX和e.clientY为鼠标的横纵坐标,

divElement.offsetLeft和divElement.offsetTop为div元素左上偏移量,

divElement.offsetWidth和divElement.offsetHeight为div元素的长度和宽度,

parentElement.offsetWidth和parentElement.offsetHeight为父元素的长度和宽度.

基本拖拽函数实现为:

</pre><pre name="code" class="javascript">function dragControl(elementId){
var element = document.getElementById(elementId);
var parent = element.parentNode;
element.onmousedown = function(e){

var mouseLeft = e.clientX,
mouseTop = e.clientY,
divLeft = element.offsetLeft,
divTop = element.offsetTop,
divWidth = element.offsetWidth,
divHeight = element.offsetHeight,
leftOffset = mouseLeft - divLeft,
topOffset = mouseTop - divTop,
parentWidth = parent.offsetWidth,
parentHeight = parent.offsetHeight;

element.onmousemove = function(e){

var mouseLeft = e.clientX,
mouseTop = e.clientY,
divLeft = element.offsetLeft,
divTop = element.offsetTop;
element.style.top = mouseTop - topOffset + 'px';
element.style.left = mouseLeft - leftOffset + 'px';

};

element.onmouseup = function(e){
element.onmousemove = null;
element.onmouseup = null;
};

};
}


为了保证其在拖拽过程中不超出父元素的边界,在整个移动过程中需要做如下处理:

if(mouseLeft - leftOffset < 0){
mouseLeft = leftOffset;
}
if(mouseTop - topOffset < 0){
mouseTop = topOffset;
}
if(parentWidth - mouseLeft < divWidth - leftOffset){
mouseLeft = parentWidth - divWidth + leftOffset;
}
if(parentHeight - mouseTop < divHeight - topOffset){
mouseTop = parentHeight - divHeight + topOffset;
}


以上代码还需要做兼容性处理,主要在两个位置需要处理:

1. 鼠标事件的获取

var e = e || window.event;

2. 阻止冒泡机制

if(e.stopPropagation){
e.stopPropagation();//W3C
}else if(window.event){
window.event.cancelBubble = true;//IE
}


至此实现了所描述的拖拽功能,并且在拖拽过程中元素不会超出其父元素的边界。



所有代码:

HTML:

<!DOCTYPE html>
<html>
<head>
<title>drag.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<link type="text/css" rel="stylesheet" href="css/drag.css">
<script type="text/javascript" src="js/drag.js"></script>

</head>

<body style="height:1080px;">
<div id="first">
<div id="second">
<div id="third">
<div id="fourth"></div>
</div>
</div>
</div>
</body>
</html>


CSS代码:

*{
margin:0px;
padding:0px;
}
#first{
width:500px;
height:500px;
background-color:#ccc;
position:relative;
left:0px;
top:0px;
cursor:move;
}
#second{
width:350px;
height:350px;
background-color:#666;
position:absolute;
left:0px;
top:0px;
cursor:move;
}
#third{
width:200px;
height:200px;
background-color:red;
position:absolute;
left:0px;
top:0px;
cursor:move;
}
#fourth{
width:100px;
height:100px;
background-color:green;
position:absolute;
left:0px;
top:0px;
cursor:move;
}


JavaScript代码:

window.onload=function(){
var dragObject = new Drag();
dragObject.drag("first");
dragObject.drag("second");
dragObject.drag("third");
dragObject.drag("fourth");
dragObject.scale("first");
dragObject.scale("second");
dragObject.scale("third");
dragObject.scale("fourth");
};
function Drag(){}

Drag.prototype.drag = dragControl;
Drag.prototype.scale = scaleControl;

function dragControl(elementId){
var element = document.getElementById(elementId);
var parent = element.parentNode;
element.onmousedown = function(e){
var e = e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else if(window.event){
window.event.cancelBubble = true;
}
var mouseLeft = e.clientX,
mouseTop = e.clientY,
divLeft = element.offsetLeft,
divTop = element.offsetTop,
divWidth = element.offsetWidth,
divHeight = element.offsetHeight,
leftOffset = mouseLeft - divLeft,
topOffset = mouseTop - divTop,
parentWidth = parent.offsetWidth,
parentHeight = parent.offsetHeight;
element.onmousemove = function(e){
var e = e || window.event;
var mouseLeft = e.clientX,
mouseTop = e.clientY,
divLeft = element.offsetLeft,
divTop = element.offsetTop;
if(mouseLeft - leftOffset < 0){ mouseLeft = leftOffset; } if(mouseTop - topOffset < 0){ mouseTop = topOffset; } if(parentWidth - mouseLeft < divWidth - leftOffset){ mouseLeft = parentWidth - divWidth + leftOffset; } if(parentHeight - mouseTop < divHeight - topOffset){ mouseTop = parentHeight - divHeight + topOffset; }
element.style.top = mouseTop - topOffset + 'px';
element.style.left = mouseLeft - leftOffset + 'px';
};
element.onmouseup = function(e){
element.onmousemove = null;
element.onmouseup = null;
};
};
}

function scaleControl(elementId){
var element = document.getElementById(elementId);
var parent = element.parentNode;
var elementWidth = element.offsetWidth,
elementHeight = element.offsetHeight,
initialWidth = elementWidth,
initialHeight = elementHeight;
element.onmousewheel = function(e){
var e = e || window.event;
if(e.stopPropagation){//w3c
e.stopPropagation();
}else if(window.event){//IE
window.event.cancelBubble = true;
}
if(e.wheelDelta > 0){
var parentWidth = parent.offsetWidth,
parentHeight = parent.offsetHeight;
elementWidth += 5;
elementHeight += 5;
var offsetx = element.offsetLeft,
offsety = element.offsetTop;
elementWidth = (elementWidth+offsetx) > parentWidth ? (parentWidth - offsetx): elementWidth;
elementHeight = (elementHeight+offsety) > parentHeight ? (parentHeight - offsety) : elementHeight;
element.style.left = offsetx + 'px';
element.style.top = offsety + 'px';
element.style.width = elementWidth + 'px';
element.style.height = elementHeight + 'px';
}else if(e.wheelDelta < 0){
var child = element.children[0],
childLeft = child.offsetLeft,
childTop = child.offsetTop,
childWidth = child.offsetWidth,
childHeight = child.offsetHeight,
parentWidth = parent.offsetWidth,
parentHeight = parent.offsetHeight;
elementWidth -= 5;
elementHeight -= 5;
elementWidth = elementWidth < initialWidth ? initialWidth : elementWidth;
elementHeight = elementHeight < initialHeight ? initialHeight : elementHeight;

if(childLeft + childWidth > elementWidth){
child.style.left = elementWidth - childWidth + 'px';
}
if(childTop + childHeight > elementHeight){
child.style.top = elementHeight - childHeight + 'px';
}
element.style.width = elementWidth + 'px';
element.style.height = elementHeight + 'px';
}
};
}


更多资讯请微信扫二维码关注我们,一起遨游互联网前端世界。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: