【问题标题】: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 进行偏移将“解决”这个问题,但是一个好的解决方法需要:

  1. 确定浏览器是否受到影响,最好不要让用户做任何事情,也不要求助于检查 userAgent(因此不要对特定浏览器版本做出任何假设)。换句话说,我们如何判断哪些浏览器的 clientXclientY 值不正确?
  2. 仅在需要解决的那些浏览器上可靠地解决问题(大概只有适用于 Android 的 Chrome 和它的特定版本,因为未来的版本可能会很好),看起来,由window.scrollX/Y 抵消是唯一的事情需要在这里完成。

【问题讨论】:

  • 我不确定,但我发现这个问题的讨论,也许它会帮助你:code.google.com/p/chromium/issues/detail?id=141840#c19
  • 除了使用正确的值来判断哪些浏览器有这种行为之外,您还有什么理由吗?与仅使用不同的方法计算 clientX/Y 相比,该解决方法使条件检查的效率更低。

标签: javascript android google-chrome touch dom-events


【解决方案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。一旦你捏和缩放页面,偏移量就会被缩放(比它应该的更大。我不知道如何解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多