拖拽的实现原理:
拖拽时,将被拖拽元素新位置的 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 中添加边缘控制就好,具体范围可以根据具体需求更改。