拖拽在js中挺常用的,不过目前有很多做拖拽的插件,H5也以及支持了拖拽事件,不过了解一下拖拽的原理也是有必要的,其实用原生js实现拖拽并不难。
首先讲一下拖拽的原理,假设浏览器上有一个元素(元素已经绝对定位了),起始位置为(mx, my),即距浏览器上方my px,左方mx px,如下图
拖拽元素的过程无非就是改变该元素的left值和top值,那么left和top值设为多少才对呢,其实这个不难,假设鼠标点击元素,并设该点击的点为(x, y), (x, y) 肯定是在带拖拽元素里的,随着鼠标的移动(是按住鼠标左右键的移动), 能得到新的鼠标位置,设为(nx, ny), 此时left值应该要等于nx - x + mx, top值为ny - y + my, 如下图
如果看懂了上面 的内容,那么接下来就用js实现一下,首先需要关注三个事件,mousedown: 鼠标按下事件,mousemove: 鼠标移动事件,mouseup: 鼠标松开事件。对于元素的初始位置(mx, my)我们这里使用element.offsetLeft和element.offsetTop来获取,鼠标按下的位置(x, y)我们可以使用event.clientX, event.clientY来获取。实现代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
html, body {
height: 100%;
}
* {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#target {
width: 100px;
height: 100px;
background: blueviolet;
border-radius: 50%;
box-shadow: 0 0 5px rgba(0,0,0,.02);
position: absolute; /*元素记得绝对定位*/
left: 10px;
top: 10px;
}
</style>
<body>
<div id="target">
</div>
<script>
!function (window, document) {
//工具函数的封装
var getById = document.getElementById.bind(document);
var getStyle = function () {
return window.getComputedStyle ? function (element, style) {
return window.getComputedStyle(element)[style]
} : function (element, style) {
return element.currentStyle[style]
}
}();
var addEvent = function () {
return document.addEventListener ? function (element, eventType, callback) {
element.addEventListener(eventType, callback, false)
} : document.attachEvent ? function (element, eventType, callback) {
element.attachEvent("on" + eventType, callback)
} : function (element, eventType, callback) {
element["on" + eventType] = callback
}
}();
function setStyle(element, css) {
for (var k in css) {
if (css.hasOwnProperty(k)) {
element.style[k] = css[k]
}
}
}
var target = getById("target"); // 获取元素
var x, y, mx, my, dx, dy, drag = false; // 需要设置一个drag来标记是否拖拽
addEvent(target, "mousedown", function (e) { // mousedown事件
e = e || window.event;
drag = true;
x = e.clientX;
y = e.clientY;
mx = this.offsetLeft;
my = this.offsetTop;
dx = x - mx;
dy = y - my;
});
addEvent(document, "mousemove", function (e) { // mousemove事件, 绑在document上比较好一点
e = e || window.event;
if (!drag) return false;
var left = e.clientX - dx, // left = nx - (x - mx)
top = e.clientY - dy; // top = ny - (y - my)
setStyle(target, {left: left + "px", top: top + "px"});
});
addEvent(target, "mouseup", function (e) { // mouseup鼠标松开
drag = false
});
}(this, document);
</script>
</body>
</html>
在浏览器上运行结果如下
当然还可以用拖拽做一些跟有趣的事情,读者可以自行尝试。