HTML5中拖曳与拖放的学习
很多场景下都需要拖曳或拖放元素的功能,例如拖曳一个登陆框或提示框等。今天温习了一下传统的拖曳方式,并学习了一下HTML5提供的原生拖放功能,总结了一下。
传统拖放元素的方式
实现步骤如下:
- 鼠标选中元素,触发
onmousedown事件 - 开始拖动,触发
onmousemove事件,元素跟随鼠标移动 - 释放鼠标,触发
onmouseup事件
其实关键就是在移动过程中将鼠标的坐标不断赋值给被拖动的元素,从而达到拖曳元素的效果。
核心实现代码如下,进行了简单的封装,使用时调用drag函数并传入点击的元素和被拖曳的元素即可:
var drag = (function() {
var flag = false // 表示是否拖曳
/**
* @param {[element]} bar:点击的元素,如登录框的头部
* @param {[element]} target:被拖曳的元素
*/
function startDrag(bar, target) {
var innerX, innerY // 鼠标距bar的左边距和上边距的距离
bar.addEventListener('mousedown', mousedown, false)
document.addEventListener('mouseup', mouseup, false)
document.addEventListener('mousemove', mousemove, false)
//获取target的CSS
var targetCSS = document.defaultView.getComputedStyle(target, null)
function mousedown() {
flag = true //鼠标点下时,表示才能被拖曳
innerX = event.clientX - parseInt(targetCSS.left)
innerY = event.clientY - parseInt(targetCSS.top)
}
function mousemove() {
if(flag) {
target.style.left = event.clientX - innerX + 'px'
target.style.top = event.clientY - innerY + 'px'
}
}
function mouseup() {
flag = false //松开鼠标后,元素无法被拖曳
}
}
return startDrag
})();
使用HTML5的原生拖放功能
默认情况下元素是不允许被拖曳的,要想拖曳某元素,在元素添加属性draggable="false"。拖动某元素时,如果拖动的区域不允许放置元素,则光标变为禁止符号(圆环中一道反斜杠);在被拖动元素上依次触发以下事件:
- dragstart
- drag
- dragend
按下鼠标并开始拖动元素时,在被拖动元素上首先触发dragstart事件,然后在拖动期间会持续触发drag事件,松开鼠标触发dragend事件。
当被拖曳的元素被拖动到一个有效放置的目标元素时,目标元素会被依次触发以下事件:
- dragenter
- dragover
- drop或dragleave
被拖曳的元素进入该目标的区域时触发dragenter事件,随后持续触发dragover事件,直到元素被被放下触发drop或dragleave事件。虽然所有元素都支持放置目标事件,但默认是不允许放置的,drop事件不会发生。把元素变为有效放置目标的方法是阻止dragenter和dragover的默认行为。还有,在Firfox 3.5+中,drop事件的默认行为是打开被放到放置目标上的URL,意思就是如果把图像拖放到放置目标上,页面就会转向图像文件。因此,还要取消drop事件的默认行为。核心代码如下:
var drag = function() {
var boxCSS = document.defaultView.getComputedStyle(box, null)
var innerX, innerY // 鼠标距别拖曳元素左边界和上边界的距离
/**
* @param {[element]} el:被拖放的元素
* @param {[element]} target:拖放的目标元素
*/
function startDrag(el, target) {
el.addEventListener("dragstart", function() {
innerX = event.clientX - parseInt(boxCSS.left)
innerY = event.clientY - parseInt(boxCSS.top)
}, false)
el.addEventListener("dragend", function() {
this.style.left = event.clientX - innerX + 'px'
this.style.top = event.clientY - innerY + 'px'
}, false)
target.addEventListener("dragenter", function() {
event.preventDefault()
}, false)
target.addEventListener("dragover", function() {
event.preventDefault()
}, false)
target.addEventListener("drop", function() {
event.preventDefault();
}, false)
}
return startDrag
}()
总结
个人感觉还是HTML5提供的原生拖放功能好用,浏览器会自动创建一个被拖动元素的半透明副本跟随光标移动,所以不用一直跟踪鼠标的位置,以改变元素的位置。还有,利用HTML的拖放效果还可以在拖曳元素和目标之间交换数据,修改拖曳效果等等。