图片懒加载原理

原理

存储图片的真实路径,把图片的真实路径绑定给一个以data开头的自定义属性data-url即可,页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片(没有请求就提高了性能)

<img data-src="imgs/1.jpg" alt="loading" class="img-item">

需要一个滚动事件,判断元素是否在浏览器窗口,一旦进入视口才进行加载,当滚动加载的时候,就把真正的图片url地址(也就是data-url里保存的值)赋值给src,并添加进img标签,就会去发送请求加载图片,真正实现了按需加载

js处理

offsetTop
<script>
     let imgs = document.querySelectorAll('img');
     let lazyload = function(){
     	let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;//获取浏览器滚动高度
     	let height = window.innerHeight; 	//获取浏览器可视高度
        for(let i=0;i < imgs.length;i++){
             //如果元素距离文档顶部的高度小于浏览器的滚动高度加浏览器的可视高度,则需要加载
        	if(imgs[i].offsetTop < scrollTop + height ){	//imgs[i].offsetTop 距离文档顶部的高度
             //性能优化 进行判断 已经加载的不会再进行加载
	               if(imgs[i].alt != 'loaded'){
	                   imgs[i].src = imgs[i].getAttribute('data-src'); //将data-src属性值赋值给src
	                   imgs[i].alt = 'loaded'
	               }
               }
           }
       }
       //调用懒加载函数,加一个防抖函数
       function throttle(method,delay){
          let timer = null;
           return function(){
               clearTimeout(timer);
               timer=setTimeout(function(){
                   method()
               },delay);
           }
       }
       window.onscroll = throttle(lazyload,200);
</script>
getBoundingClientRect

getBoundingClientRect返回一个矩形对象,包含上下左右的偏移值

 for (let i=0;i < imgs.length;i++) {
        //计算方式和第一种方式不同
        if (imgs[i].getBoundingClientRect().top < window.innerHeight) { 
           if(imgs[i].alt != 'loaded'){
	           imgs[i].src = imgs[i].getAttribute('data-src'); //将data-src属性值赋值给src
	           imgs[i].alt = 'loaded'
	       }
        }
  }

其中,getBoundingClientRect().top 为元素相对于窗口的位置;window.innerHeight 为当前窗口的高度;当元素对于窗口的位置小于当前窗口的高度时,那自然处于了窗口可视区了。

intersectionObserve

Intersection Observer 的作用是它能够观察可视窗口与目标元素产生的交叉区域。简单来说就是当用它观察我们的图片时,当图片出现或者消失在可视窗口,它都能知道并且会执行一个特殊的回调函数,我们就利用这个回调函数实现我们的操作。

<script>
        let io = new IntersectionObserver(function (entires) {
            //图片进入视口时就执行回调
            entires.forEach(item => {
                // 获取目标元素
                let oImg = item.target
                // console.log(item);
                // 当图片进入视口的时候,就赋值图片的真实地址
                if (item.intersectionRatio > 0 && item.intersectionRatio <= 1) {
                    oImg.setAttribute('src', oImg.getAttribute('data-url'))
                }
            })
        })
        Array.from(imgs).forEach(element => {
            io.observe(element)  //给每一个图片设置监听
        });
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值