Chrome for Android 的错误 clientX 和 clientY 行为的解决方法是啥?
Posted
技术标签:
【中文标题】Chrome for Android 的错误 clientX 和 clientY 行为的解决方法是啥?【英文标题】:What's a workaround for Chrome for Android's incorrect clientX and clientY behavior?Chrome for Android 的错误 clientX 和 clientY 行为的解决方法是什么? 【发布时间】:2012-11-22 12:48:39 【问题描述】:在 android 版本 16 和 18 的 Chrome 中(至少)存在错误报告 clientX
和 clientY
的错误。如果页面被滚动,clientX/Y
的值至少对于 touchstart
事件是不正确的,但不是 click
事件。这里有一个错误:
https://code.google.com/p/chromium/issues/detail?id=117754
里面有这个例子,你可以自己试试:http://www.apprisant.com/tab/cd.html
我在这里用画布做了一个类似的例子:http://codepen.io/simonsarris/full/dJcvn
这些示例适用于其他移动浏览器(包括普通的旧版 Android 浏览器),但 Android 版 Chrome 似乎在滚动时(至少在某些)触摸事件上破坏了 clientX/Y。
有趣的是,clientX 和 clientY 在 click
事件上并没有像在 touchstart
上那样被破坏。
我的问题是,让 clientX 和 clientY 在浏览器中一致工作的最佳解决方法是什么? 似乎用 window.scrollX
和 window.scrollY
进行偏移将“解决”这个问题,但是一个好的解决方法需要:
-
确定浏览器是否受到影响,最好不要让用户做任何事情,也不要求助于检查 userAgent(因此不要对特定浏览器版本做出任何假设)。换句话说,我们如何判断哪些浏览器的
clientX
和 clientY
值不正确?
仅在需要解决的那些浏览器上可靠地解决问题(大概只有适用于 Android 的 Chrome 和它的特定版本,因为未来的版本可能会很好),看起来,由window.scrollX/Y
抵消是唯一的事情需要在这里完成。
【问题讨论】:
我不确定,但我发现这个问题的讨论,也许它会帮助你:code.google.com/p/chromium/issues/detail?id=141840#c19 除了使用正确的值来判断哪些浏览器有这种行为之外,您还有什么理由吗?与仅使用不同的方法计算 clientX/Y 相比,该解决方法使条件检查的效率更低。 【参考方案1】:只需使用e.pageY - window.scrollY
代替e.clientY
(或相应地使用X
)。
e.pageY
将告诉您事件发生的位置,而通过window.scrollY
偏移将“删除由于滚动而出现在屏幕外的空白区域”。您可以有条件地检查e.pageY - window.scrollY === e.clientY
,但由于解决方法为您提供了正确的值,并且您必须计算它以检查它,这将是违反直觉的。
【讨论】:
稍等,有问题。很快会修改答案,很抱歉造成混淆。 使用e.pageY - window.scrollY
代替e.clientY
似乎很有可能假设它总是等于正确的值。我们可以确定吗?
如果您想在当前视口上获取事件发生的位置,可以。 window.scrollY
是屏幕到文档顶部的距离,e.pageY
是事件到文档顶部的距离。有一种情况你必须小心,那就是如果你使用一些 fo-scolling 包装元素而不是窗口来滚动页面。不知道你为什么会这样,但它就是这样。
我不确定这是否足够。我需要在尽可能多的 DOM 情况下防弹的画布点击和触摸的坐标代码
@SimonSarris 实际上,我没有测试过,它甚至可以在可滚动元素内部使用。【参考方案2】:
我会先检查一下
<meta name="viewport" content="width=device-width, initial-scale=1">
被使用。这解决了移动浏览器应用程序中的许多位置问题,尤其是 Android。不确定它是否会帮助您解决特定问题,但值得一试。
【讨论】:
【参考方案3】:您可以在画布上订阅touchstart
事件并使用.offset()
和e.pageX
来获取画布内的位置。
$('#my-canvas').on('touchstart', function (startEvent)
var offset = $(this).offset();
$(this).on('touchmove', function (moveEvent)
var pos =
x: moveEvent.pageX - offset.left,
y: moveEvent.pageY - offset.top
);
);
【讨论】:
这适用于所有可能的 DOM 配置吗?我曾经使用 PageX/Y 和偏移量,但不得不停止,因为 Firefox 处理偏移量的方式与其他浏览器不同。我似乎记得内联 div 是个问题,但我现在不记得了。canvas
默认是内联的并且可以工作。你必须尝试看看。此外,您还可以使用特殊情况的 Chrome 来使用它,并将 clientX
用于其他浏览器。
这实际上适用于所有浏览器和操作系统,除了 chrome over android。一旦你捏和缩放页面,偏移量就会被缩放(比它应该的更大。我不知道如何解决它。以上是关于Chrome for Android 的错误 clientX 和 clientY 行为的解决方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何用 Chrome for Android 做远程遥控 debugging