tip:有问题或者需要大厂内推的+我脉脉哦:丛培森 ٩( ‘ω’ )و
今天给大家谈谈这个拖拽功能的实现
一来是想复习一下这个小知识,二来是看到网上都是absolute绝对定位实现的,感觉有一定局限性
所以自己写了一下用relative相对定位来实现的拖拽效果
#原生js绝对定位实现拖拽#
首先我们来思考一下拖拽功能用到的事件
拖拽无非是鼠标按下点击物体(DOM节点)
鼠标移动,物体移动
鼠标抬起,物体停止拖拽
所以这里我们需要绑定三个事件
mousedown、mousemove、mouseup
不过通过刚才我们所思考的
mousemove和mouseup事件触发应该是由一个鼠标按下的前提
我们可以利用一个布尔变量储存状态表示当前是否鼠标按下
或者干脆在mousedown事件处理函数中去绑定mousemove、mouseup
那么现在我们大脑里有了这样一个实现拖拽功能函数的蓝图
(主要是逻辑,绑定事件等等兼容问题我就不具体实现了b( ̄▽ ̄)d)
//伪代码
function drag(ele){
ele.onmousedown = function(){
...
document.onmousemove = function(){
...
}
document.onmouseup = function(){
...
}
}
}
既然要让DOM节点被拖拽,当然不能少了作为参数的元素
下面我们来仔细分析一下拖拽的事件:
既然是绝对定位实现,那我们就加一个容错机制
让鼠标按下的时候就为它添加css样式绝对定位
我们在拖拽的过程中实际上就是改变元素的left和top
可是在拖拽过程中怎样知道它的left和top值应该是什么呢?
拖拽中,有一个量是不变的,那就是光标相对DOM节点左上角的坐标是不变的
而鼠标移动时我们可以获取到的是光标相对于视窗的坐标
也就是说
DOM节点相对于视窗坐标 = 光标相对于视窗坐标 - 光标相对于DOM节点坐标
这样逆向思考思路就清晰多了
不知道我这样描述大家能不能看懂
所以我们要在mousedown中处理的就是获取那个不变的量------光标相对于DOM节点的坐标
于是每次移动都根据公式获取DOM节点的相对于视窗的坐标(left与top值)
鼠标抬起清理事件
理清了这些,我们来封装这个函数
//待改进
function drag(ele){
var posX, posY;
ele.onmousedown = function(e){
this.style.position = 'absolute';//元素绝对定位
//获取光标相对于DOM节点的坐标
posX = e.clientX - parseInt(window.getComputedStyle(this,false)['left']);
posY = e.clientY - parseInt(window.getComputedStyle(this,false)['top']);
ele.onmousemove = function(e){
//改变DOM节点相对于视窗坐标
this.style.left = e.clientX - posX + 'px';//加上像素不要忘了
this.style.top = e.clientY - posY + 'px';
}
ele.onmouseup = function(){
this.onmousemove = null;//鼠标抬起就应该解除事件
this.onmouseup = null;
}
}
}
这里多说一句,其实posX = e.offsetX; posY = e.offfsetY;
和上面的那一长串是一样的
这是IE的非标准方法,虽然我现在使用的无比强大的chrome也好使…
然后我们在来使用一下我们刚刚封装的函数