源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图片懒加载</title> <style> .box { width: 800px; height: 800px; border: 1px solid; overflow: auto; }
.img { width: 200px; height: 200px; border: 1px solid; display: block; margin: 40px auto; } </style> </head> <body> <div class="box"> <img class="img" src="https://picsum.photos/200/200" alt="1"> <img class="img" src="https://picsum.photos/200/200" alt="2"> <img class="img" src="https://picsum.photos/200/200" alt="3"> <img class="img" src="https://picsum.photos/200/200" alt="4"> <img class="img" src="" data-src="https://picsum.photos/200/200" alt="5"> <img class="img" src="" data-src="https://picsum.photos/200/200" alt="6"> <img class="img" src="" data-src="https://picsum.photos/200/200" alt="7"> <img class="img" src="" data-src="https://picsum.photos/200/200" alt="8"> <img class="img" src="" data-src="https://picsum.photos/200/200" alt="9"> </div> </body> </html> <script> var box = document.getElementsByClassName('box')[0]; var imgs = document.getElementsByClassName('img'); box.onscroll = throttle(handleScorllChange);
// 节流函数 function throttle (fn, delay=500) { let oldTime = Date.now(); return function (...args) { let newTime = Date.now(); if (newTime - oldTime >= delay) { fn.apply(null, args); oldTime = Date.now(); } } } function handleScorllChange () { let boxHeight = box.clientHeight; let scrollTop = box.scrollTop; for (let i = 0; i < imgs.length; i++){ if (imgs[i].offsetTop - 100 < boxHeight + scrollTop && imgs[i].getAttribute('data-src')) { imgs[i].src = imgs[i].getAttribute('data-src') } } } </script>
|
解析
监听图片容器元素的滚动事件,通过每张图片的 offsetTop(距离父元素顶部的距离)判断图片是否即将显示,即将显示时给 src 赋值。
html 部分
通过 picsum.photos 生成图片,初次加载时显示的图片直接设置 src
js 部分
图片容器元素添加滚动监听事件,会高频触发影响浏览器性能,故使用节流算法,节流请看节流与防抖。
1 2 3
| var box = document.getElementsByClassName("box")[0]; var imgs = document.getElementsByClassName("img"); box.onscroll = throttle(handleScorllChange);
|
监听事件:循环图片元素,判断图片元素是否“ 即将出现 ”,即 图片距父元素顶部的距离 < 容器高度 + 已经滚过的距离,这里“ -100 ”是为了预留足够的加载时间使图片再提前一些加载。
1 2 3 4 5 6 7 8 9 10 11 12
| function handleScorllChange() { let boxHeight = box.clientHeight; let scrollTop = box.scrollTop; for (let i = 0; i < imgs.length; i++) { if ( imgs[i].offsetTop - 100 < boxHeight + scrollTop && imgs[i].getAttribute("data-src") ) { imgs[i].src = imgs[i].getAttribute("data-src"); } } }
|