拖曳元素(一)
在Web页中实现元素的拖曳,方法之一是通过一系列 mouse* 事件完成:mousedown,鼠标按键按下时令元素可拖动的布尔变量为真;mousemove,鼠标移动时若此时可拖动变量为真则改变元素的 left 和 top 属性令其跟随鼠标移动;mouseup,鼠标按键弹起时令可移动变量为假,元素不能再移动。
对鼠标若干事件的监听有讲究,不同的监听事件捆绑的对象不同,应根据需要或是被拖动的元素,或是其父元素,或是 document。特别注意的是,监听鼠标移动事件不能捆绑给被拖动元素自身,道理好比你不能站在箱子上拖动箱子。
下面通过实例实现元素的拖曳操作:id="wrap1" 的父元素的作用是给 id="box1" 的子元素提供坐标参照,使用“父相对定位+子绝对定位”的布局方式。实例不限制子元素的拖曳范围,意思是,子元素可以拖动到页面的任何地方;若需要限定在父元素中拖曳也很简单:监听父元素的鼠标移动事件,并在计算 _x 和 _y 坐标值时增加一些条件判断语句纠偏。
<style>
#wrap1 {
width: 600px;
height: 200px;
border: 1px solid;
position: relative;
}
#box1 {
position: absolute;
width: 100px;
height: 50px;
background-color: lightblue;
display: grid;
place-items: center;
user-select: none;
}
</style>
<div id="wrap1">
<div id="box1">拖曳我</div>
</div>
<script>
let draggable = false, /* 可拖动变量 */
currentbox = null; /* 当前拖动对象 */
box1.onmousedown = (e) => {
draggable = true; //鼠标指针在盒子上按下时可拖动
currentbox = box1; //待拖动的盒子标识
};
//基于文档的鼠标移动事件
document.onmousemove = (e) => {
if(!draggable && !currentbox) return; //移动条件不具备时不执行后面语句
let rect = wrap1.getBoundingClientRect(); //获取父元素对象 : 返回一系列父元素的属性值
/* 计算子元素位置
① left 属性值计算 : 指针X坐标 - 父元素left值 - 子元素宽度÷2
② top 属性值计算 : 指针Y坐标 - 父元素top值 - 子元素高度÷2
clientX : 鼠标指针客户端水平坐标
clientY : 鼠标指针客户端纵向坐标
offsetWidth : 元素宽度
offsetHeight : 元素高度
*/
let _x = e.clientX - rect.left - currentbox.offsetWidth / 2,
_y = e.clientY - rect.top - currentbox.offsetHeight / 2;
//驱动元素移动
currentbox.style.cssText += `
left: ${_x}px;
top: ${_y}px;
`;
};
//基于文档的鼠标按键弹起事件
document.onmouseup = () => {
draggable = false; //鼠标指针在文档中松开后不可拖动
currentbox = null; //清除待拖动盒子标识
};
</script>
前一篇: CSS关键帧动画文本效果:逐行出场(封装二)
下一篇: 拖曳元素(二)
发表评论:
评论列表 [1条]
#1 | 飞飞 于 2024-9-6 19:00 发布: 这个拖动可到任意一个地方,跑到框外也是可以。。
