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 中(至少)存在错误报告 clientXclientY 的错误。如果页面被滚动,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.scrollXwindow.scrollY 进行偏移将“解决”这个问题,但是一个好的解决方法需要:

    确定浏览器是否受到影响,最好不要让用户做任何事情,也不要求助于检查 userAgent(因此不要对特定浏览器版本做出任何假设)。换句话说,我们如何判断哪些浏览器的 clientXclientY 值不正确? 仅在需要解决的那些浏览器上可靠地解决问题(大概只有适用于 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

如何用 Chrome for Android 做远程遥控 debugging

Chrome 67 for Android发布

android 常见问题解决方法(持续更新中....)

Chrome for Android显示自动填充即使自动填充:关闭

Chrome for Android 中的手势启动事件模拟