原生实现元素的拖拽

1,383 阅读2分钟

最近在学习jQuery,真的很强大!在jQuery的ui插件里有一个draggable,可以搞定拖拽,不用再用原生的去计算差值,同时还提供了一些常用值得获取方法。

jQuery的UI插件官网API

$(".dragger").draggable({
	"containment" : ".stage" , 
	"axis": "X",
	"drag" : function(event , ui){
		var left = ui.position.left;
		var top = ui.position.top;
	}
});

上面代码中列出常用的三个属性

containment

可以理解是被拖拽的元素.dragger活动的舞台,只在:后面的.stage的范围内活动;

官网的API Multiple types supported:

  • Selector: The draggable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.
  • Element: The draggable element will be contained to the bounding box of this element.
  • String: Possible values: "parent", "document", "window".
  • Array: An array defining a bounding box in the form [ x1, y1, x2, y2 ].

axis

被拖拽元素的活动方向,X表示只沿x轴拖动,Y表示只沿y轴拖动。

drag

drag的值为一个函数,函数内可以理解为拖拽之后要做的事情。 其中ui提供了position和offset方法,获取拖拽对象的实时定位left和top值,通过ui.position.left获取,这个值会随着元素的重新定位而改变。

position Type: Object Current CSS position of the helper as { top, left } object. The values may be changed to modify where the element will be positioned. This is useful for custom containment, snapping, etc.

offset Type: Object Current offset position of the helper as { top, left } object.

下面用原生的方法实现拖拽

思路:在鼠标点击时,记录当时的位置,鼠标移动在点击之后,所以在onmousedown里注册onmousemove事件,计算出鼠标实时位置与起始位置的差值,将差值赋值给被拖动的元素,就可以看起来好像是在拖拽一样的效果了。

  • html和css部分
	#stage{
		width: 1200px;
		height: 800px;
		margin: 50px;
		border: 1px solid #eee;
		position: relative;
	}
	.dragger{
		position: absolute;
		width: 200px;
		height: 80px;
		border: 1px solid #eee;
		box-shadow: 2px 2px 5px rgba(0,0,0,.4);
		background-image: -webkit-linear-gradient(top, skyblue, white 70%);
	}

	<div id="stage">
		<div class="dragger"></div>
	</div>
  • js代码
		var stage = document.getElementById("stage");
		var dragger = document.getElementsByClassName("dragger")[0];
		var startLeft = 0,
			startTop = 0,
			diffX,
			diffY;
		//鼠标点击事件添加给将要拖拽的盒子
		dragger.onmousedown = function(event){
			//记录开始点击的位置
			var startX = event.pageX;
			var startY = event.pageY;
			//添加鼠标移动事件给stage
			stage.onmousemove = function(event){
				//计算出差值
				diffX = event.pageX - startX;
				diffY = event.pageY - startY;
				//设置给dragger定位值
				dragger.style.left = startLeft + diffX + 'px';
				dragger.style.top = startTop + diffY + 'px';
			}

		}

		document.onmouseup = function(event){
			stage.onmousemove = null;

			startLeft += diffX;
			startTop += diffY;
		}

最后的鼠标离开事件添加给document,因为当鼠标离开时,事件会冒泡到最外层的document,因此直接社在document上。