0x01 瀑布流(Masonry)

最近在研究瀑布流布局,调查一番发现有许多实现方式。权衡一下最终还是选择了 JS + transform 定位去实现。

  • 能够按行排序
  • transform + transition 在拖动时展示动画比较方便
  • 与其它方式相比效果更好,兼容也更好

原理:先把第一行铺满,接着找最短的一列添加新图片,直到所有图片都添加完毕。

0x02 图片加载

瀑布流一般与无限滚动相互搭配,每次从后台取一定量的图片,滚动条快到底后再次请求。这里最好是后台返回时就把图片的大小给返回。

否则需要前端去判断图片大小,会带来无法妥协的体验问题。图片需要 load 后才能获取大小,一般有两种做法:

  • Promise.all 等待所有图片加载完毕后再添加到DOM中

    问题在于图片较多以及加载速度较慢时,会带来较长的等待时间

  • 加载完一张图片直接添加到到DOM中

    顺序会乱,与技术选型的条件相悖

0x03 Intersection Observer

加载展示
加载展示

使用Intersection Observer监听瀑布流Container下方的 div,如果在可视范围内,则拉取新图片。但问题在于Intersection Observer在一开始只会触发一次,callback中动态添加了图片我们无法确定图片是否多到让滚动条出现,从而可以正常触发滚动逻辑。

所以在 Observer 的 Callback 中,需要添加相关逻辑

/**
 * If there's still blank area in first page
 */
if( entries[0].isIntersecting ) {

    /**
     * Un-observe scroll-notify element
     */
    io.unobserve( scroll );

    /**
     * After a period of time, re-observe it
     * So the intersection observer callback will be triggered to add more images
     */
    setTimeout(() => {
        io.observe( scroll );
    }, 100 );
}

0xFF 更多阅读