前言

在我的导航站点项目编写过程中,不同一级分类可以切换显示隐藏,每一个一级分类下都有很多导航地址(图标+名称)效果如下

考虑到性能问题,可以先通过调用api查询基础的导航站点信息渲染展示,然后通过IntersectionObserver API实现图标的懒加载

多种懒加载方法

参考 https://juejin.cn/post/7080544007834730510

实现思路

先将图标的url保存在img标签的自定义属性上,等api监听到这个站点信息渲染了就用这个url去设定img标签的src属性。

代码实现

每一个导航标签的html代码如下,每个标签都先设定了一个默认的占位图标,真实图标利用谷歌的api获取,格式如下:https://www.google.com/s2/favicons?domain=${site.url}`,只需要传入站点的ip地址,就可以自动获取到对应的站点图标。

<a class="nav-link" target="_blank" :href="site.url">
  <div class="icon">
    <img
      class="nav-icon"
      :src="defaultIcon"
      :data-src="`https://www.google.com/s2/favicons?domain=${site.url}`"
    />
  </div>
  <div
    class="nav"
    :title="site.description ? site.description : '暂无备注'"
  >
    {{ site.name }}
  </div>
</a>

然后利用IntersectionObserver API封装一个图标懒加载方法如下

const lazyLoadIcons = () => {
  const imgs = document.querySelectorAll('.nav-icon');

  const options = {
    rootMargin: '0px',
    threshold: 0.1,
  };
  const imageObserver = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      // 通过该属性判断元素是否出现在视口内
      if (entry.isIntersecting) {
        const img: any = entry.target;
        img.src = img.dataset.src;
        // 图片加载完成后解除监听
        imageObserver.unobserve(img);
      }
    });
  }, options);

  imgs.forEach((img) => {
    imageObserver.observe(img);
  });
};