懒加载

54 阅读1分钟

1.getBoundingClientRect 实现

1. 在img 元素上绑定一个data-original属性,存放src。
2. 获取视图高度,通过documentElement.clientHeight;
3. getBoundingClientRect().top<视图高度
4. item.src = item.dataset.original
5. item.removeAttribute('data-original')属性。
  function lazyLoadFunc() {
    console.log('lazyLoadFunc_start');
    let elementArr = document.querySelectorAll("img[data-original]");
    let vieHight = document.documentElement.clientHeight;//可视高度
    Array.prototype.forEach.call(elementArr, (item) => {
      let rect = item.getBoundingClientRect();
      if(rect.bottom>=0&&rect.top<vieHight){
        let img = new Image();
        img.src = item.dataset.original;
        item.src = img.src;
        item.removeAttribute('data-original');
      }
    });
  }

2.offsetTop + scrollTop实现

1、2、4、5一样,仅2判断有区别
    let scrollTop = document.body.scrollTop||document.documentElement.scrollTop;
    
    item.offsetTop<=scrollTop+document.documentElement.clientHeight
    

IntersectionObserver

IntersectionObserver的作用是监听目标元素与祖先元素是否有相交(默认是浏览器的视口)
const config = {
    root: null, //监听元素的祖先元素dom对象,默认为浏览器可视窗口
    rootMargin: "0px 0px 0px 0px", //监听元素距离多远触发回调函数
    threshold: "0", //1 表示整个元素都进入可视范围才触发。 0 表示刚相交就触发
  };
  let observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        entry.target.src = entry.target.dataset.original;
        observer.unobserve(entry.target);
      }
    });
  }, config);
  useEffect(() => {
    const imgs = document.querySelectorAll("img");
    Array.prototype.forEach.call(imgs,(img)=>{
    observer.observe(img);
    })
  }, []);