【问题标题】:Can't prevent `touchmove` from scrolling window on iOS无法阻止“touchmove”在 iOS 上滚动窗口
【发布时间】:2018-09-05 02:55:37
【问题描述】:

我们试图在我们的 iOS 网络应用程序上滚动一个元素,同时阻止窗口本身滚动。我们正在捕获窗口上的touchmove 事件,以编程方式滚动元素并(试图)通过在事件上调用preventDefault 来阻止窗口本身滚动。

很遗憾,这在 Mobile Safari 中不起作用。窗口继续在我们的元素下方滚动。这个问题听起来与https://bugs.webkit.org/show_bug.cgi?id=163207 中描述的 Webkit 错误一模一样,但据说这个问题已在 iOS 10.3 中修复,而我正在运行 11.3。

捕获touchforcestart 并调用preventDefault 似乎确实阻止了窗口的滚动,但我们在touchstart 中调用它,这似乎“为时已晚”,因为窗口仍在滚动。只有在下次调用 touchstart 时才会阻止滚动。

对正在发生的事情有任何想法吗?我们很困惑,因为这显然是一个错误,但似乎已经在一段时间前修复了。

【问题讨论】:

    标签: ios scroll mobile-safari preventdefault touchmove


    【解决方案1】:

    您需要将 preventDefault 绑定到两个事件:touchmovetouchforcechange 以使其在 ios 11 中工作,例如

    document.addEventListener('touchmove', this.preventDefault, {passive: false});
    document.addEventListener('touchforcechange', this.preventDefault, {passive: false});
    

    而且你应该在touchstart之前绑定它们

    如果您将它们绑定在 touchstartdragStart 处理程序中,它们只能阻止在下一次拖动时滚动。

    【讨论】:

    • touchforcechange?没有它似乎可以工作?
    【解决方案2】:

    我最近遇到了同样的问题。在注册touchmove 事件监听器时,您需要传递{ passive: false }。例如

    document.addEventListener('touchmove', function(e) {
        e.preventDefault();
    }, { passive: false });
    

    这是因为在与 iOS 11.3 捆绑在一起的 Safari 11.1 中,文档触摸事件侦听器现在默认是被动的。此更改记录在 Safari 11.1 release notes

    网络 API

    • [...]
    • 更新了根文档触摸事件侦听器以使用被动模式提高滚动性能并减少崩溃。

    【讨论】:

    • 好东西,谢谢!我们在touchstart 处理程序中添加了touchmove 侦听器,出于某种原因,我似乎也需要取消它(使用preventDefault)以取消touchmove,即使关闭了被动也是如此。 { passive: false }touchstarttouchmove 事件在我们处理它们后都被取消,它似乎工作得很好。
    • 是否可以在应用此代码后仅在文档内部启用特定 div 中的滚动? @user9576791
    • 如何在点击页面时删除此事件监听器? @user9576791
    • 很好,但现在的问题是您也没有滚动页面。
    • 非常感谢。我一直看到没有被动部分的答案,所以没有用。
    猜你喜欢
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 2021-08-18
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    相关资源
    最近更新 更多