JavaScript可拖动div简单实现

作者: 麦草CMS 日期: 2019/03/13 19:48:49

最近在写JavaScript可拖动div插件。写了个雏形,我想这个可拖动div雏形可以作为前端新手的参考,就放了出来。同时也增加一篇垃圾博文。


JavaScript可拖动div的拖动过程有三个关键事件产生:mousedown、mousemove、mouseup三个鼠标事件,对应的移动端事件是touchstart、touchmove、touchend三个触摸事件。


首先在drag构造函数中给可拖动div的可拖动区域元素的mousedown、touchstart事件绑定回调函数start;然后在start函数中为document的mousemove、touchmove事件绑定回调函数move,为document的mouseup、touchend事件绑定回调函数end,mousedown、touchstart事件发生时触发start函数;move函数在mousemove、touchmove事件发生时根据鼠标移动位置定位可拖动div;end函数在mouseup、touchend事件发生时移除document的mousemove、touchmove及mouseup、touchend的绑定。


这里用到事件处理相关的封装在http://mycms.xyz/blog/view.php?aid=8一文中。代码中用到MyCMS.popup.alert,是我写的一个JavaScript弹窗插件MyPopup,在本站可以找到。


drag.js代码如下:

(function(w){
	function Drag(options){
		var self = this, options = options || {};
		if(!options.container || !options.container.nodeType || options.container.nodeType !== 1){
			MyCMS.popup.alert("被拖拽主体(container)必需,且为元素节点!");
			return;
		}
		this.container = options.container;
		var css = window.getComputedStyle ? window.getComputedStyle(this.container) : this.container.currentStyle;
		if(css.position == "static"){
			MyCMS.popup.alert("被拖拽主体(container)定位方式(position)不能是static!");
			return;	
		}
		if(!options.area || !options.area.nodeType || options.area.nodeType != 1){
			this.area = this.container;
		}else{
			this.area = options.area;
		}
		var flag = false, elem = this.area;
		while(elem !== null){
			if(elem === options.container){
				flag = true;
				break;
			}
			elem = elem.offsetParent;
		}
		if(!flag){
			MyCMS.popup.alert("可拖拽区域(area)必须为被拖拽主体(container)或其子级元素,且为元素节点!");
			return;
		}
		var absPos = MyCMS.utils.getAbs(this.container);
		var relPos = MyCMS.utils.getRel(this.container);
		this.position = {
			x: absPos.x,
			y: absPos.y,
			X: relPos.x,
			Y: relPos.y,
			offsetX: this.container.offsetLeft,
			offsetY: this.container.offsetTop
		};
		this.screenX = 0;
		this.screenY = 0;
		this.eIndexs = {};
		this.area.style.cursor = "move";
		MyCMS.event.addEvent(this.area, "mousedown", function(e){MyCMS.event.preventDef(e);self.start(e);});
		MyCMS.event.addEvent(this.area, "touchstart", function(e){MyCMS.event.preventDef(e);self.start(e)});
	}
	Drag.prototype.start = function(e){
		var self = this;
		if(e.changedTouches && e.changedTouches.length === 1){
			e = e.changedTouches[0];
		}
		var eIndex1 = MyCMS.event.addEvent(document, "mousemove", function(evt){MyCMS.event.preventDef(e);self.move(evt)});
		var eIndex2 = MyCMS.event.addEvent(document, "touchmove", function(evt){MyCMS.event.preventDef(e);self.move(evt)});
		var eIndex3 = MyCMS.event.addEvent(document, "mouseup", function(){
			self.end();
		});
		var eIndex4 = MyCMS.event.addEvent(document, "touchend", function(){
			self.end();
		});
		this.screenX = e.screenX;
		this.screenY = e.screenY;
		this.eIndexs = {
			eIndex1: eIndex1,
			eIndex2: eIndex2,
			eIndex3: eIndex3,
			eIndex4: eIndex4
		};
	};
	Drag.prototype.move = function (e){
		if(e.changedTouches && e.changedTouches.length === 1){
			e = e.changedTouches[0];
		}
		var self = this,
		currentScreenX = e.screenX,
		currentScreenY = e.screenY,
		diffX = currentScreenX - this.screenX,
		diffY = currentScreenY - this.screenY;
		this.screenX = currentScreenX;
		this.screenY = currentScreenY;
		//MyCMS.popup.open(JSON.stringify(self));
		function fixed(){
			self.position.X = self.position.X + diffX;
			self.position.Y = self.position.Y + diffY;
			self.container.style.top = self.position.Y + "px";
			self.container.style.left = self.position.X + "px";
			self.area.innerHTML = self.position.X;
		}
		function absolute(){
			self.position.offsetX = self.position.offsetX + diffX;
			self.position.offsetY = self.position.offsetY + diffY;
			self.container.style.top = self.position.offsetY + "px";
			self.container.style.left = self.position.offsetX + "px";
			self.area.innerHTML = self.position.x;
		}
		function relative(){
			self.position.offsetX = self.position.offsetX + diffX;
			self.position.offsetY = self.position.offsetY + diffY;
			self.container.style.top = self.position.offsetY + "px";
			self.container.style.left = self.position.offsetX + "px";
			self.area.innerHTML = self.position.offsetX;
		}
		var css = window.getComputedStyle ? window.getComputedStyle(this.container) : this.container.currentStyle;
		switch(css.position){
			case "fixed":
				fixed();
				break;
			case "absolute":
				absolute();
				break;
			case "relative":
				relative();
				break;
		}
	};
	Drag.prototype.end = function (){
		var self = this;
		//alert(this.eIndexs.eIndex1);
		MyCMS.event.removeEvent(this.eIndexs.eIndex1);
		MyCMS.event.removeEvent(this.eIndexs.eIndex2);
		MyCMS.event.removeEvent(this.eIndexs.eIndex3);
		MyCMS.event.removeEvent(this.eIndexs.eIndex4);
	};
	w.Drag = Drag;
	//Drag.prototype. = function (){};
}(window));

drag.html如下:

<!DOCTYPE html>
<html>
<head>
<title>拖拽</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript" src="js/dao.js"></script>
<script type="text/javascript" src="js/modules/drag/drag.js"></script>
</head>
<body>
<div  style="position:relative;width:400px; height:800px; border: 1px solid red;top:200px; left:80px;">
<div id="t" style="position:relative;width:100px; height:80px; border: 1px solid red;top:3px; left:80px;">
<div id="f" style="width:100px; height:60px; border: 1px solid red;clear:both;"></div>
<div>relative</div>
</div>
<div id="t1" style="position:fixed;width:100px; height:80px; border: 1px solid red;top:3px; left:80px;">
<div id="f1" style="width:100px; height:60px; border: 1px solid red;"></div>
fixed
</div>
<div id="t2" style="position:absolute;width:100px; height:80px; border: 1px solid red;top:110px; left:80px;">
<div id="f2" style="width:100px; height:60px; border: 1px solid red;"></div>
absolute
</div>
</div>
<script>
new Drag({container: document.getElementById("t"),area: document.getElementById("f")});
new Drag({container: document.getElementById("t1"),area: document.getElementById("f1")});
new Drag({container: document.getElementById("t2"),area: document.getElementById("f2")});
</script>
</body>
</html>


我还说什么呢?
0.0019760131835938