IOS 防止 touchmove 事件被固定元素后面的 body 捕获

IOS Prevent touchmove event being catched by the body behind fixed element

我有一个覆盖整个屏幕并需要滚动的固定元素。

IOS 有人们所说的 'rubbing banding' 这种行为的例子,你可以看看这些 gif:

http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/

问题是,当 rubber banding 发生并拉下我的固定元素(显示它覆盖的内容)时,用户的手指可能最终会落在正在 overlay-ed 的内容上.

发生这种情况时,所有 touchmove 事件都不会在我覆盖屏幕的固定元素上触发,而是在我的固定元素覆盖的 body 上触发。

我知道你可以防止 body 像这样滚动:

body.noscroll{
    position:fixed;
    overflow:hidden;
}

但这是防止滚动的解决方案。

这不是解决方案,因为一旦 touchmove 事件在 overlay-ed 内容上触发一次,只有当用户将手指从屏幕上移开时,它才会停止。

简而言之,用户可能会滚动我的固定元素,到达顶部,使橡皮筋弹出并在 body 而不是固定元素上滑动,因为橡皮筋会显示 body。

即使元素在橡皮圈发生后弹回原位,touchmove 事件仍然停留在 body 元素上,直到用户将手指从屏幕上移开。

我不知道在这里做什么。以某种方式禁用 body 的 touchmove 事件似乎是个好主意,但我的固定元素在里面,它仍然需要滚动能力。

关于如何处理这个问题有什么想法或提示吗?

编辑:

一个简单的 jsfiddle:

https://jsfiddle.net/pq88zLLx/1/

这仅适用于 IOS,但仅当您滑入橡皮筋显示的内容时。

在移动浏览器上处理内部滚动的固定元素确实没有好的解决方案。

除了Safari我没有测试过其他浏览器,但我了解到其他浏览器也不太喜欢这种组合。

最好和最灵活的解决方案是让您的 full screen 元素 absolute 定位。这将解决滑动和定位的常见问题。

But what if my element is in a relative container?

那么你运气不好,需要抓住你的元素,将其从 dom 中移除并在打开 [=] 时将其尽可能高地放置在 dom 中13=]元素.

之后您需要将元素放回原来的位置。据我所知,他们最好的做法是为您留下一个占位符 append/prepend。 dom 无法为您提供元素的确切位置,因此如果您不想更改元素的顺序,则必须这样做。

如果您觉得可以改进,请随时对此答案发表评论或建议。