移动端无法获取event.clientX和event.clientY的解决办法

最近在制作一个实现类似于手机的锁屏手势密码效果的页面时,由于需要应用获取canvas中,手指划过的位置,于是遇到了一些小问题。
众所周知,在PC端,我们通常用event.clienX或者event.clientY来获取手指的坐标,可是在移动端,打开开发者模式,调试touch事件时,这一值通过console.log始终返回是undefined。

通过查询,我发现了TouchEvent里面有touches,targetTouches以及changedTouches这几个属性。其中:

touches 是当前屏幕上所有触摸点的列表

targetTouches 是当前DOM上所有触摸点的列表//尽量使用这个代替touches

changedTouches 详细说一说,要分开来解读:对于 touchstart 事件, 这个 TouchList 对象列出在此次事件中新增加的触点。对于 touchmove 事件,列出和上一次事件相比较,发生了变化的触点。对于 touchend ,列出离开触摸平面的触点(这些触点对应已经不接触触摸平面的手指)。对于 touchenter 事件和 touchleave 事件,列出从上一次事件触发到这一次事件触发的过程中,离开或者进入目标 element 的触点。

这里引用segmentfault上一个问题中的回答来解释
假如有两个div,div2绑定了一个touch事件,最初将手指1放在div2,那么会触发事件,此时touches、targetTouches和changedTouches都是一样的,包含手指1。接着,将手指2放在div1,同时将手指3放在div2,此时事件再次触发,touches为3个手指,targetTouches为手指1和手指3(DOM内手指),changedTouches变为了手指3和手指1的位置(新增加的触摸点)。

用一张图片来生动描述就是:
这里写图片描述

这里我觉得这个回答还有待进一步考虑,因为PC的开发者工具,模拟移动端,鼠标就一个,不知道怎么模拟多个手指,也就无从去console.log这多个事件,所以暂时还没想到用什么方法来验证我下面的思考:

我的思考是假如,手指2和3不是同时放下的有一点时间差(比如手指长度不一样),尤其是当手指3先放下,那么已经触发了touchStart事件,是不是changedTouches中就不会存放手指2了。而且退一步来说,就算两个手指真的都同时放下,事件触发点是div2, div1中那个手指真的会被changedTouches计算在内么?如果有大神试过请在评论中帮我解答一下! 拜谢!

当然因为真实项目中,你应用这三个属性时,大部分情况是不会出现需要考虑我如上的情况的业务需求的,毕竟只需要获取事件触发点的手指就行了嘛。

那么回到最初的问题,移动端无法获取event.clientX和event.clientY肿么办!想必看完整篇文章的你,已经有了一定的思路。就如我项目中,做手势密码,那么很简单了,我监听的事件是touchmove。

那么就在touchmove事件的handler中,使用event.changedTouches[0].clientX来获取就行了!!

大功告成,继续做我的手势密码去!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现根据鼠标选择的图片区域,在指定区域中显示放大的图像,您可以修改鼠标事件的处理程序,以实现选择区域并在指定区域中显示放大图像的功能。以下是修改后的代码: ```javascript function showPopup(imageSrc) { var popup = document.createElement("div"); var popupImg = document.createElement("img"); var scale = 1; var isDragging = false; var startX, startY, translateX, translateY; var startX2, startY2, endX, endY; // 用于选择图片区域的坐标 // 设置弹出窗口中的图片 popupImg.src = imageSrc; popupImg.style.transform = `scale(${scale})`; // 设置悬浮窗样式 popup.style.position = "fixed"; popup.style.width = "80%"; popup.style.height = "80%"; popup.style.backgroundColor = "transparent"; popup.style.zIndex = "9999"; // 添加图片到悬浮窗 popup.appendChild(popupImg); document.body.appendChild(popup); // 居中弹出窗口... // 鼠标按下事件,开始拖动图片或选择图片区域 popupImg.onmousedown = function (event) { startX = event.clientX; startY = event.clientY; translateX = 0; translateY = 0; // 记录选择图片区域的起始坐标 startX2 = event.clientX - popup.offsetLeft; startY2 = event.clientY - popup.offsetTop; isDragging = true; }; // 鼠标移动事件,拖动图片或选择图片区域 popupImg.onmousemove = function (event) { if (isDragging) { var deltaX = event.clientX - startX; var deltaY = event.clientY - startY; translateX += deltaX; translateY += deltaY; popupImg.style.transform = `scale(${scale}) translate(${translateX}px, ${translateY}px)`; startX = event.clientX; startY = event.clientY; } }; // 鼠标松开事件,停止拖动图片或选择图片区域 popupImg.onmouseup = function () { isDragging = false; // 记录选择图片区域的结束坐标 endX = event.clientX - popup.offsetLeft; endY = event.clientY - popup.offsetTop; // 计算选择图片区域的宽度和高度 var width = Math.abs(endX - startX2); var height = Math.abs(endY - startY2); // 创建放大区域的元素,并设置样式 var zoomArea = document.createElement("div"); zoomArea.style.position = "absolute"; zoomArea.style.left = startX2 + "px"; zoomArea.style.top = startY2 + "px"; zoomArea.style.width = width + "px"; zoomArea.style.height = height + "px"; zoomArea.style.border = "1px dashed red"; zoomArea.style.background = "rgba(0, 0, 0, 0.2)"; // 添加放大区域到弹出窗口 popup.appendChild(zoomArea); }; // 鼠标离开事件,停止拖动图片或选择图片区域 popupImg.onmouseleave = function () { isDragging = false; }; // 键盘事件监听器,按下键盘上的Escape键退出放大图片 document.onkeydown = function (event) { if (event.key === "Escape") { popup.style.display = "none"; } }; } ``` 通过添加选择图片区域的功能,您可以在鼠标按下和鼠标松开事件中记录起始坐标和结束坐标,并根据这些坐标创建一个放大区域的元素,将其添加到弹出窗口中。 请尝试使用上述修改后的代码,并确保在调用`showPopup`函数时传递正确的参数。如果问题仍然存在,请提供更多关于问题的详细信息,以便我们能够更好地帮助您解决问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值