原生js实现拖拽功能

JavaScript023

原生js实现拖拽功能,第1张

物体的拖拽移动,其实是触发了三个鼠标相关事件

拖拽的实现原理:

拖拽时,将被拖拽元素新位置的 left 和 top 重新赋值给被拖拽元素的 left 和 top ,覆盖上一个位置的值,鼠标按下是在元素内部,所以还要减去鼠标按下位置相对于元素内部本身的 left 和 top 值

很简单 需要三个事件 onmousedown onmousemove onmouseup

并给需要拖动的节点增加一个属性叫droping(这个属性表示节点是不是正处于拖拽状态)下面给出一份演示

onmousedown 控制节点扩展的属性droping为true(表示可以移动节点了)

onmousemove 控制节点的位置(判断是否可以移动如果是就移动)

ommouseup控制节点的扩展属性为false(表示不能移动节点了)

<!DOCTYPE HTML>

<html>

<head>

<title>演示</title>

<style type="text/css">

</style>

</head>

<body>

<div id="dropDiv">

  我可以拖动

</div>

<script type="text/javascript">

function dropDivFun(Element){

//设置节点的定位为fixed

Element.style.position="fixed"

//获取事件对象函数 方便获取事件的clientX

function getEvent(){

if(event){

e=event

}else if(window.event){

e=window.event

}else{

e=arguments.callee.arguments[0]

}

return e

}

//添加mousedown事件

Element.addEventListener("mousedown",function(){

var e=getEvent()

if(!Element.droping){

//设置droping为true并记录初始的位置

Element.droping=true

Element.start_x=e.clientX-Element.offsetLeft

Element.start_y=e.clientY-Element.offsetTop

}

})

Element.addEventListener("mousemove",function(){

var e=getEvent()

//移动节点

if(Element.droping){

Element.style.left=e.clientX-Element.start_x+"px"

Element.style.top=e.clientY-Element.start_y+"px"

}

})

Element.addEventListener("mouseup",function(){

if(Element.droping){

//设置droping为false并释放初始的变量

Element.droping=false

Element.start_x=null

Element.start_y=null

}

})

}

//为节点添加drop事件

dropDivFun(document.getElementById("dropDiv"))

</script>

</body>

</html>

该演示演示了使用原生js给节点拖动

因为需要计算元素的位置变化,所以需要掌握几个关于位置的api

点击需要拖动元素时,获取该元素的初始位置。

鼠标移动期间 获取元素当前的位置信息

计算

进行事件监听

拖拽的实现原理:通过事件mousedown(事件的触发) →mousemove(事件的控制) →mouseup(事件的清除),拖拽的过程就是mousemove阶段;

问题产生的原因:因为mousemove 的间隔性触发,当两次mousemove事件触发的间隔中,鼠标移动距离出了element的范围,就会产生鼠标脱离element范围,拖拽就停止,

解决方法: 将mousemove事件挂在docment,而不是对应的element,此时鼠标滑动只要不出docment范围就不会触发上述情况。

拖动事件完成的动作时是:mousedown(事件的触发) →mousemove(事件的控制) →mouseup(事件的清除) 但是mouseup的时候 同时会触发 点击事件(如果元素上面有点击事件的话)

处理办法:记录mousedown(记录开始时间) →mousemove→mouseup(记录结束时间) 的时间 根据时间长短判断是进行了点击事件还是进行了拖拽事件。

正常需求的话 就希望拖拽元素只在屏幕的可视范围内进行拖拽,不能跑出去。

在onmousemove 中添加边缘控制就好,具体范围可以根据具体需求更改。