拖拽效果在网站中是很常见的一种效果,其实现原理很简单,不过其中也隐藏了不少关键知识点,比如说焦点丢失问题等。接下来看看具体代码是怎么实现的。
css样式(注意:元素要定位,不然没有效果)
1 .box { 2 position: absolute; 3 width: 100px; 4 height: 100px; 5 background-color: #f00; 6 cursor: move; 7 }
html结构(这里为什么使用行内样式,因为后面操作需要获取元素的css样式,原生的js只能获取行内样式css。)
<div class="box" id="box" style="left: 0px;top: 0px;"> </div>
核心代码
1 var box = document.getElementById("box"); 2 3 box.onmousedown = down; //绑定鼠标按下事件 4 5 function down(e) { 6 7 e = e || window.event; //处理兼容 8 9 this["startX"] = e.clientX; //在绑定元素身上添加自定义属性 记录鼠标的起始位置与元素的坐标值 10 this["startY"] = e.clientY; 11 this["startL"] = parseFloat(this.style.left); 12 this["startT"] = parseFloat(this.style.top); 13 14 //IE和火狐提供了setCapture方法防止鼠标移动过快,焦点丢失问题,但是谷歌不兼容 15 if(this.setCapture) { 16 this.setCapture(); 17 } else { 18 var that = this; //如果不支持,就把事件绑定到document上,不论鼠标移动多快,都不会丢失焦点 19 document.onmousemove = function(e) { 20 move.call(that, e); //这里用call改变了this指向,因为如果不使用call,此时执行move方法的this是window,移动元素无效果。 21 }; 22 document.onmouseup = function() { 23 up.call(that, e); 24 }; 25 } 26 } 27 28 function move(e) { 29 e = e || window.event; 30 31 var curL = (e.clientX - this["startX"]) + this["startL"]; 32 var curT = (e.clientY - this["startY"]) + this["startT"]; 33 34 var minL = 0, 35 minT = 0, 36 maxL = (document.documentElement.clientWidth || document.body.clientWidth) - this.offsetWidth, 37 maxT = (document.documentElement.clientHeight || document.body.clientHeight) - this.offsetHeight; 38 //边界值 39 curL = curL < minL ? minL : (curL > maxL ? maxL : curL); 40 curT = curT < minT ? minT : (curT > maxT ? maxT : curT); 41 42 this.style.left = curL + "px"; 43 this.style.top = curT + "px"; 44 } 45 46 function up(e) { 47 e = e || window.event; 48 49 if(this.releaseCapture) { //鼠标抬起,解绑事件 50 this.releaseCapture(); 51 } else { 52 document.onmousemove = null; 53 document.onmouseup = null; 54 } 55 }
其中关键点就是事件中的e对象,这个对象提供了很多有用的信息,我们常用到clientX,clientY,pageX,pageY等。