无法阻止iOS上滚动窗口的"touchmove"

Mat*_*ner 24 scroll mobile-safari ios preventdefault touchmove

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

不幸的是,这在Mobile Safari中不起作用.窗口继续在我们的元素下滚动.问题听起来与https://bugs.webkit.org/show_bug.cgi?id=163207中描述的Webkit错误完全相同,但该问题在iOS 10.3中已得到修复,而我运行的是11.3.

捕获touchforcestart和调用preventDefault似乎确实阻止了窗口的滚动,但是我们正在调用它touchstart,因为窗口仍然滚动,这似乎"太晚了".滚动仅在下次touchstart调用时被阻止.

关于发生了什么的任何想法?我们感到困惑,因为这显然是一个错误,但它似乎已经修复了一段时间.

小智 63

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

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
}, { passive: false });
Run Code Online (Sandbox Code Playgroud)

这是因为默认情况下,文档触摸事件侦听器在Safari 11.1中是被动的,它与iOS 11.3捆绑在一起.Safari 11.1 发行说明中记录了此更改:

Web API

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

  • 应用此代码后,是否可以仅在文档内部启用特定div中的滚动?@ user9576791 (6认同)
  • 好东西,谢谢!我们在`touchstart`处理程序中添加了`touchmove`监听器,由于某种原因,即使被动关闭,我也需要取消它(使用`preventDefault`)来取消`touchmove`.在我们处理它们之后,"{passive:false}"和"touchstart"和"touchmove"事件都被取消了,它看起来效果很好. (5认同)
  • 很好,但是现在的问题是您也不在滚动页面。 (2认同)

Use*_*007 7

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

document.addEventListener('touchmove', this.preventDefault, {passive: false});
document.addEventListener('touchforcechange', this.preventDefault, {passive: false});
Run Code Online (Sandbox Code Playgroud)

你应该在 touchstart 之前绑定它们

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