avatar

目录
图片懒加载的两种方法-节流 IntersectionObserver

第一种:

以下代码皆在 React 中测试使用

使用 window 上的 onscroll 事件,配合封装好的 throttle 节流函数实现图片的懒加载。

render 函数内:

render() {
    const data = [
      {
        url: 'https://dwz.cn/Jwg1UQEj',
        text: '图片1-1',
      },
      {
        url: 'https://dwz.cn/w8t4A0WD',
        text: '图片1-2',
      },
      {
        url: 'https://dwz.cn/l1nYpL4U',
        text: '图片1-3',
      },
      {
        url: 'https://dwz.cn/2XrYhRBX',
        text: '图片1-4',
      },
      {
        url: 'https://dwz.cn/00pSTOtm',
        text: '图片1-5',
      },
      {
        url: 'https://dwz.cn/Hg1aIh3e',
        text: '图片1-6',
      },
    ];
    return(
      <ul className={styles.list}>
        {Object.keys(data).length ? data.map(item => {
          return (
            <li key={item.url} >
              <h2>{item.text}</h2>
              <img className={styles.lazyImg} src='https://dwz.cn/qLQmSywT' _src={item.url} alt={item.text}/>
            </li>
          )
        }) : 'loading'}
      </ul>
    )
  }

componentDidmount 函数内

// 获取所有的需要懒加载的图片元素
const imgs = document.querySelectorAll('.'+styles.lazyImg);
// 首次执行 手动触发滚动事件
this.lazyLoad(imgs);
// 节流函数
const lazyLoad = this.throttle(e => this.lazyLoad(imgs), 400, true);window.onscroll - lazyLoad

lazyLoad 方法

lazyLoad = (imgs) => {
    imgs.forEach(item => {
      console.log('lazyLoad');
      const top = item.getBoundingClientRect().top;
      if (top < window.innerHeight && item.src !== item.getAttribute('_src')) {
        item.src = item.getAttribute('_src');
      }
    })
  };

// 节流函数的封装
throttle = (fn, wait, immediate) => {
let timer = null;
let callNow = immediate;
return function() {
const args = arguments,
that = this;
if (callNow) {
fn.apply(that, args);
callNow = false
}
if (!timer) {
setTimeout(() => {
fn.apply(that, args);
timer = null;
}, wait)
}
}
};

第二种

使用 IntersectionObserver 接口,具体使用方法请去 MDN 查看

const io = new IntersectionObserver(callback);
 // 获取所有的需要懒加载的图片元素
const imgs = document.querySelectorAll('.'+styles.lazyImg);
function callback(entries) {
      entries.forEach((item) => {
        if(item.isIntersecting){
          item.target.src = item.target.getAttribute('_src');
          io.unobserve(item.target)
        }
      })
}
imgs.forEach((item)=>{
   io.observe(item)
})

componentDidmount 函数内

本文引荐 https://www.jianshu.com/p/84a86e41eb2b

IntersectionObserver 亦可以实现 导航栏吸顶效果

文章作者: kshao
文章链接: https://blog.ksh7.com/2019/03/17/e5-9b-be-e7-89-87-e6-87-92-e5-8a-a0-e8-bd-bd-e7-9a-84-e4-b8-a4-e7-a7-8d-e6-96-b9-e6-b3-95-e8-8a-82-e6-b5-81-intersectionobserver/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 kshao-blog
打赏
  • 微信
    微信
  • 支付寶
    支付寶