说在前面
🎈元素拖拽功能大家应该都不陌生了吧,今天我们一起来看看怎么编写一个
vue指令
来实现元素拖拽功能吧!
效果展示
体验地址
实现思路
1、初始化
let startX,
startY,
currentX = 0,
currentY = 0;
el.style.position = "relative";
el.parentNode.style.position = "relative";
el.style.cursor = "pointer";
- (1)指令钩子函数 inserted:当被绑定的元素被插入到 DOM 中时,该函数被调用。
- (2)初始化变量:
- startX 和 startY 用于存储鼠标按下或触摸开始时的相对位置。
- currentX 和 currentY 用于存储元素当前的偏移量。
- (3)设置元素样式:
- el.style.position = "relative":确保元素是相对定位的,这样移动时不会影响其他元素的布局。
- el.parentNode.style.position = "relative":将父元素也设置为相对定位,这是为了确保子元素的定位是相对于父元素的。
- el.style.cursor = "pointer":改变鼠标光标的样式,提供视觉反馈,表明元素可以被点击和拖动。
2、添加事件监听器
- 对于鼠标操作,添加 mousedown 和 mouseup 事件监听器。
- 对于触摸操作,添加 touchstart 和 touchend 事件监听器。
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}
3、事件处理函数:
- onMouseMove 和 onTouchMove:在鼠标移动或触摸移动时调用,用于更新元素的位置。
- onMouseUp 和 onTouchEnd:在鼠标松开或触摸结束时调用,用于移除 mousemove 和 touchmove 事件监听器,结束拖拽操作。
- 拖拽函数 drag:更新元素的 top 和 left 样式,使元素移动到 currentX 和 currentY 指定的位置。
function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
drag(el);
}
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
drag(el);
}
function drag(el) {
el.style.top = currentY + "px";
el.style.left = currentX + "px";
}
完整代码
export default {
inserted: function (el) {
let startX,
startY,
currentX = 0,
currentY = 0;
el.style.position = "relative";
el.parentNode.style.position = "relative";
el.style.cursor = "pointer";
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
drag(el);
}
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
drag(el);
}
function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}
function drag(el) {
el.style.top = currentY + "px";
el.style.left = currentX + "px";
}
},
};
组件库
组件文档
目前该组件也已经收录到我的组件库,组件文档地址如下: jyeontu.xyz/jvuewheel/#…
组件内容
组件库中还有许多好玩有趣的组件,如:
- 悬浮按钮
- 评论组件
- 词云
- 瀑布流照片容器
- 视频动态封面
- 3D轮播图
- web桌宠
- 贡献度面板
- 拖拽上传
- 自动补全输入框
- 图片滑块验证
等等……
组件库源码
组件库已开源到gitee,有兴趣的也可以到这里看看:gitee.com/zheng_yongt…
觉得有帮助的可以点个star~
有什么问题或错误可以指出,欢迎pr~
有什么想要实现的组件或想法可以联系我~
公众号
关注公众号『前端也能这么有趣
』,获取更多有趣内容。
发送『组件库
』获取源码
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。