这篇文章发布于 2026年11月6日,星期五,17:51,归类于 JS API。 阅读 67 次, 今日 66 次 没有评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12481
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
一、还在mousedown个棒槌
关于拖拽的文章,我之前写过至少两三篇,之前实现逻辑都是这样。
一个拖拽标志量,一个存储数据的变量。
mousedown后标志量开启,存储初始数据,
然后在document文档上绑定mousemove,实时计算位置。
等mouseup后再恢复和处理。
用了很多年,自我感觉也挺好的,眼睛闭着都能手写出来。
实际上,上面这套实现已经过时了,且过时很久了。
现在还在使用mousedown实现拖拽效果,那就是个棒槌了。
应该使用pointerdown、pointerup这类事件(PC、Mobile双通),同时,移动的事件也不需要绑定在document或者<body>元素上了,直接写在触发元素上即可!
有人会问了,要是拖动太快,鼠标从触发元素上移出,岂不是pointermove事件不会触发?
是有这个问题,不过,此事件在设计的时候就考虑到这种场景了,于是设计了setPointerCapture方法,专门针对此问题。
二、setPointerCapture与拖拽
setPointerCapture可以捕获事件的pointerId,在鼠标或手势释放之前,后续所有事件都将以该捕获元素为目标。
所以拖拽的时候,不要担心目标元素会丢失。
眼见为实,直接看案例,假设一个球是ball:
<div class="ball" id="ball"></div>
那么所有拖拽事件都可以绑定在 ball 元素上,通过setPointerCapture捕获,不要担心拖拽行为那么容易丢失。
JS代码参考示意:
let dragging = false;
let offsetX = 0;
let offsetY = 0;
ball.addEventListener("pointerdown", function (event) {
dragging = true;
// 最关键代码就是我
ball.setPointerCapture(event.pointerId);
...
});
ball.addEventListener("pointermove", function (event) {
if (dragging == false) {
return;
}
...
});
const stopDrag = function (event) {
dragging = false;
if (ball.hasPointerCapture(event.pointerId)) {
ball.releasePointerCapture(event.pointerId);
}
};
ball.addEventListener("pointerup", stopDrag);
ball.addEventListener("pointercancel", stopDrag);
ball.addEventListener("lostpointercapture", stopDrag);
鼠标或手指按下的时候setPointerCapture,抬起的时候释放releasePointerCapture,就可以完成体验流畅的拖拽效果啦。
眼见为实,您可以狠狠地点击这里:setPointerCapture实现小球拖拽demo

演示效果是AI生成的,虽然不是我的UI美学风格,但是算了,省心啊,嘿嘿😋。
三、在唠叨点什么,水些字数
哎呀,内容有点少了,再水些内容吧。
说到Pointer,我不自觉又联想到了requestPointerLock,这个是用来实现无限滚动的,属于JS Pointer Lock的内容,之前写文章介绍过:鼠标无限移动 JS API Pointer Lock简介
CSS的pointer-events:none可以干掉JS pointer相关的事件,不过却阻止不了focus交互。
还有啥,好有啥,我想想……
哦,还有个touch-action,与触摸有关的,可以阻止滚动啥的,可以防止自怼拖拽和原生滚动冲突。
然后老的setCapture()方法已经废弃了,万不可使用。
噢啦,差不多就这么多了。
感谢大家的阅读,周末愉快,祝我爆护。
这是我上周末钓的,168五小时,钓得都铺出来了,😁😁。

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12481
(本篇完)
- 鼠标无限移动 JS API Pointer Lock简介 (0.486)
- CSS touch-action简介与treated as passive错误解决 (0.374)
- 移动端双指缩放图片JS事件的实践心得 (0.374)
- 今天才知道,Web网页也能阻止息屏了 (0.374)
- 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型 (0.140)
- JS获取上一访问页面URL地址document.referrer实践 (0.140)
- 小tips: 点击页面出现富强、民主这类文字动画效果 (0.140)
- 使用document.scrollingElement控制窗体滚动高度 (0.140)
- 幸好document.readyState还是有点锤子用的 (0.140)
- JS文本选区变化selectionchange事件实践小记 (0.140)
- 如何disabled禁用所有表单input输入框元素 (RANDOM - 0.112)