如何获取元素点击时的鼠标位置 实现点击复制位置提示
最优实现方案
你完全不需要绑定全局mousemove事件持续追踪鼠标位置——浏览器触发点击事件时,事件对象本身就自带点击瞬间的鼠标坐标,和你之前给文本字段绑定事件取坐标的逻辑完全一致,没有额外的追踪成本。
针对Markdown内容无法直接给元素加class的问题,用下面的方案就能实现,兼容性和性能都拉满:
- 把所有需要支持点击复制的目标词汇,在Markdown源文件里写成统一锚点的链接格式:
[待复制的文本](#click-copy),这种写法完全符合标准Markdown语法,所有渲染器都能正常解析,不需要额外改渲染配置。 - 用jQuery的事件委托机制统一监听这类链接的点击事件,不需要等Markdown渲染完成后逐个遍历元素绑定,哪怕是动态加载的Markdown内容也能自动生效。
改造后可直接运行的代码
$(document).ready(function(){ // 全局仅绑定1个事件监听器,处理所有点击复制需求 $(document).on('click', 'a[href="#click-copy"]', function(e) { // 阻止链接默认的锚点跳转行为 e.preventDefault(); const copyContent = $(this).text().trim(); // 直接从当前点击事件对象取坐标,不需要提前存储鼠标位置 navigator.clipboard.writeText(copyContent).then(() => { displaySuccessMessage(e.pageX, e.pageY, "已复制"); }); }) }); function displaySuccessMessage(x,y,text) { const msg_width = 80; x = x - (msg_width/2); let $tipNode = $('#successMessageTemp'); // 提示节点只创建一次,后续复用,避免反复增删DOM if (!$tipNode.length) { $tipNode = $(`<div id="successMessageTemp" style="text-align:center;vertical-align:middle;width:${msg_width}px;position:absolute;top:0;left:0;border:0 solid grey;background:#fff;margin:2px;display:none;z-index:9999;padding:4px 8px;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,0.15)"></div>`); $('body').append($tipNode); } // 清除之前的隐藏定时器,避免连续点击时提示异常 clearTimeout($tipNode.data('hideTimer')); $tipNode.css({ top: y + 'px', left: x + 'px' }).text(text).show('slow'); const timer = setTimeout(() => $tipNode.hide('slow'), 2000); $tipNode.data('hideTimer', timer); }
原理说明
所有鼠标类交互事件触发时,浏览器会自动把事件发生瞬间的鼠标坐标(
pageX/pageY为相对页面根节点的坐标,clientX/clientY为相对视口的坐标)填充到事件对象上,只有需要实现鼠标跟随类的非点击实时效果时,才需要监听mousemove持续记录位置,单纯获取点击坐标完全不需要额外的全局监听。
这个方案的额外优势:
- 性能开销极低,全局仅绑定1个点击监听器,不管页面有多少个可复制词汇都不会增加额外监听成本
- 完全符合标准Markdown语法,不需要修改渲染器配置,迁移到任何支持Markdown的平台都能正常渲染
- 链接形式的可交互元素天然有视觉提示,用户能直观感知到这是可点击的元素,交互体验更符合预期
内容的提问来源于stack exchange,提问作者Scudo
相关产品推荐
相关产品推荐

