图片懒加载
场景
一个网页会包含很多的图片,例如淘宝京东这些购物网站,商品图片很多,如果在首页就全部加载的话,会影响渲染速度(比如出现白屏)和浪费带宽,为了解决以上问题,提高用户体验,就出现了懒加载方式来减轻服务器的压力,优先加载可视区域的内容,其他部分等进入了可视区域再加载,从而提高性能。
原理
一张图片就是一个img标签,浏览器是否发起请求图片是根据img的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给img的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。
实现
- 加载loading图片进行占位
- 判断哪些图片要加载
- 将loading图片替换真图片
代码语言:javascript
复制
<body> <div class="img-list"> <img src="./loading.gif" data-src="1.jpg" width="300" height="300"> <img src="./loading.gif" data-src="2.jpg" width="300" height="300"> <img src="./loading.gif" data-src="3.jpg" width="300" height="300"> <img src="./loading.gif" data-src="4.jpg" width="300" height="300"> <img src="./loading.gif" data-src="5.jpg" width="300" height="300"> <img src="./loading.gif" data-src="6.jpg" width="300" height="300"> <img src="./loading.gif" data-src="7.jpg" width="300" height="300"> </div>
<script> // 节流 function throttle(fn, interval, option) { var lastTime = 0 var timer var option = option || {} var trailing = option.trailing || false return function () { var _this = this var _arguments = arguments var newTime = new Date().getTime() if (timer) { clearTimeout(timer) } var result return new Promise((resolve, reject) => { if (newTime - lastTime > interval) { result = fn.apply(_this, _arguments) resolve(result) lastTime = newTime } else if (trailing) { timer = setTimeout(() => { result = fn.apply(_this, _arguments) resolve(result) }, interval); } }) } } // 懒加载 function lazy() { // 获取页面滚动条卷去的高度 let bodyScrollHeight = parseInt(document.body.scrollTop || document.documentElement.scrollTop) // 获取页面高度 let windowHeight = window.innerHeight // 获取所有img标签 var imgs = document.querySelectorAll('img') // 延迟加载图片 setTimeout(() => { for (let i = 0; i < imgs.length; i++) { // 获取每个img标签距离body的高度 let imgScrollTop = imgs[i].offsetTop /* (1)如果img标签距离body的高度 小于 页面高度+被卷去的高度,则代表当前img标签在可视区域,加载图片 (2)由于如果从最底部加载的话,最开头的图片一定符合(1),因此要判断img标签距离body的高度有没有大于滚动的高度, 大于滚动高度了才加载图片 */ if (imgScrollTop >= bodyScrollHeight && imgScrollTop < windowHeight + bodyScrollHeight) { // 遍历img的所有属性 for (let j = 0; j < imgs[i].attributes.length; j++) { // 如果有data-src属性,将它的值赋给src if (imgs[i].attributes[j].name == 'data-src') { imgs[i].src = imgs[i].attributes[j].value // 赋值后data-src就没用了,移除掉它 imgs[i].removeAttribute('data-src') } } } } }, 300); } // 刚进首页不触发滚动事件,因此要先加载一次 lazy() // 监听滚动事件 // window.addEventListener('scroll', lazy) // 用节流函数优化性能 window.addEventListener('scroll', throttle(lazy, 100, { trailing: true })) </script>
</body>