关闭

[JavaScript学习]用面向对象方法实现拖拽效果

标签: javascript面向对象拖拽
798人阅读 评论(0) 收藏 举报
分类:

这两天又进一步学习了下JavaScript的面向对象方法,也看了简单的拖拽案例,顺便就尝试自己写写简单的拖拽效果作为练习


目标:实现子DIV在父DIV内的拖拽效果,并且不会突破父DIV边缘,在接近父DIV边缘时,自动吸附到边缘;

想法:

  1. 鼠标在子DIV区域内按下,子DIV获取onclick事件,计算鼠标位置和子DIV左边缘和上边缘的距离;
  2. 鼠标移动,生成一个虚线框的DIV,大小和子DIV一直,左边缘和上边缘与鼠标位置距离和之前测得的鼠标位置与子DIV距离保持一致,跟随鼠标移动,实现拖拽效果;
  3. 若鼠标移动范围超过父DIV边缘,则让虚线框DIV边缘位置与父边框边缘位置保持一致,从而防止突破父DIV边缘;
  4. 当鼠标在父边框内接近父边框边缘一定距离时,将父边框边缘位置赋给虚线框DIV边缘位置,从而实现吸附效果;
  5. 鼠标按键松开,将虚线框DIV的位置信息赋给子DIV,同时消除虚线框DIV。

实现:

HTML:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>拖拽</title>
</head>
<body>
	<div id="div1">
		<div id="div2"></div>
	</div>
</body>
</html>

CSS:

#div2{
	width: 80px;
	height: 80px;
	background: red;
	position: absolute;
}
#div1{
	width: 400px;
	height: 400px;
	background:gray;
	position: relative;
}
.box {
	border: dashed 1px black;
	position: relative;
}

JavaScript:

window.onload = function(){
	new Drag("div1", "div2", "20");
}
//拖拽对象构建函数
function Drag(fatherId, childId, touchDis){
	var _this = this;
	this.touchDis = touchDis;
	this.disX = 0;
	this.disY = 0;
	this.oDiv1 = document.getElementById(fatherId);
	this.oDiv2 = document.getElementById(childId);
	//绑定鼠标点下事件处理函数
	this.oDiv2.onmousedown = function(ev){
		_this.mouseDown(ev);
	}
}
//鼠标点下事件处理函数
Drag.prototype.mouseDown = function (ev){
	var _this = this;
	var oEvent = ev || event;
	//保存鼠标位置和子DIV的左边缘与上边缘距离
	this.disX = oEvent.clientX - this.oDiv2.offsetLeft + document.documentElement.scrollLeft;
	this.disY = oEvent.clientY - this.oDiv2.offsetTop + document.documentElement.scrollTop;
	//创建虚线框DIV(oBox),并添加到父DIV的子节点上
	this.oBox = document.createElement('div');
	this.oBox.className = 'box';
	this.oBox.style.width = this.oDiv2.offsetWidth - 2 + 'px';
	this.oBox.style.height = this.oDiv2.offsetHeight - 2 + 'px';
	this.oBox.style.left = this.oDiv2.offsetLeft + 'px';
	this.oBox.style.top = this.oDiv2.offsetTop + 'px';
	this.oDiv1.appendChild(this.oBox);
	//简单的鼠标事件捕获兼容处理,并绑定相应的事件处理函数
	if(this.oDiv2.setCapture){
		this.oDiv2.onmousemove = function(ev){
			_this.mouseMove(ev);
		}
		this.oDiv2.onmouseup = function(){
			_this.mouseUp();
		}
		this.oDiv2.setCapture();
	}else{
		document.onmousemove = function(ev){
			_this.mouseMove(ev);
		}
		document.onmouseup = function(){
			_this.mouseUp();
		}
	}
	//禁用浏览器默认操作
	return false;
}
//鼠标移动事件处理函数
Drag.prototype.mouseMove = function (ev){
	var oEvent = ev || event;
	var left = oEvent.clientX - this.disX + document.documentElement.scrollLeft;
	var top = oEvent.clientY - this.disY + document.documentElement.scrollTop;
	//检测鼠标是否在父DIV内,防止子DIV突破父DIV边界,同时通过判断鼠标和父DIV边缘距离实现边缘吸附效果
	if(left < this.touchDis){
		left = 0;
	}else if(left > this.oDiv1.offsetWidth - this.oDiv2.offsetWidth - this.touchDis){
		left =  this.oDiv1.offsetWidth - this.oDiv2.offsetWidth;
	}

	if(top < this.touchDis){
		top = 0;
	}else if(top > this.oDiv1.offsetHeight - this.oDiv2.offsetHeight - this.touchDis){
		top = this.oDiv1.offsetHeight - this.oDiv2.offsetHeight;
	};
	this.oBox.style.left = left + 'px';
	this.oBox.style.top = top + 'px';
};
//鼠标松开事件处理函数
Drag.prototype.mouseUp = function(){
	//解除鼠标点下和移动事件处理函数绑定
	this.onmousemove = null;
	this.onmousup = null;
	//奖虚线框DIV位置信息赋给子DIV
	this.oDiv2.style.left = this.oBox.offsetLeft + 'px';
	this.oDiv2.style.top = this.oBox.offsetTop + 'px';
	//移除虚线框DIV
	this.oDiv1.removeChild(this.oBox);
	if(this.oDiv2.releaseCapture){
		this.oDiv2.releaseCapture();
	}
};
实现效果如下:传送门

写完后发现其实这样用面向对象方法来实现好像很蛋疼,好像没什么实用性,不过权当练习了……


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8134次
    • 积分:180
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论