2

这个问题是关于触摸、滚动和交叉观察回调的执行顺序。

我有一个简单的移动网络应用程序,它有一个可滚动的列表视图,其中每个项目的高度为 100 像素,并且我在视口上放置了交叉点观察器,但上边距为 -100 像素(rootMargin: "-100px 0px 0px 0px")。

以这种方式完成,以便我的列表项在向上滚动时就可以被观察到。

路口观察者是这样的:

const io = new IntersectionObserver(viewportBottomObserverCallback, {
  root: null,
  rootMargin: "-100px 0px 0px 0px",
  threshold: [0, 1]
})

我有 touchmove 处理程序、滚动处理程序和交叉点观察者回调。

现在,只要我触摸并向上滑动,我就会看到执行这些处理程序/回调的一致行为。首先onTouchMove被调用,然后onScroll被调用,最后viewportBottomObserverCallback被调用。总是这样吗?这个问题很重要,因为如果我知道这些 DOM 事件总是按此顺序调用,那么我的代码将变得非常确定。通常,任何其他 DOM 事件都不是这种情况。

为了更好地可视化它,我附上了我的 chrome 分析器的屏幕截图。蓝色里面的部分是我的交叉点观察者回调。

在此处输入图像描述

编辑:

我正在 chrome 上以响应模式测试这个,设备是 iPhone 6/7/8。

还有一个问题:任务(交叉点观察者)到事件循环的计算和排队是否仅在update layer tree完成后才发生,特别是这个任务 - https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo

4

1 回答 1

1

总结一下 -

所有微任务都在任何其他事件处理、渲染或任何其他宏任务发生之前完成。这保证了微任务之间的应用程序基本相同(没有鼠标坐标变化,没有新的网络数据等)。

所以是的!它是确定性的。

退后一步,浏览器使用事件循环在脚本、渲染、绘画、网络、事件之间切换。在事件循环的每一轮中,都会执行一个宏任务。宏任务是诸如 UI 事件 (mousemove)、DOM 操作和 setTimeout 之类的操作。微任务在宏任务出队后运行。所以像IntersectionObserverPromise.resolve这样的事情在渲染和绘画之前发生在 Microtask 队列中。

https://www.w3.org/TR/intersection-observer/#event-loop

https://javascript.info/event-loop

于 2020-02-29T03:59:36.890 回答