监听滚动事件和IntersectionObserver()实现图片懒加载
图片懒加载
| <p>...</p> <p>...</p> <p>...</p> <p>...</p> <img data-src="1.jpg" /> <img data-src="2.jpg" /> <img data-src="3.jpg" /> <img data-src="4.jpg" /> <img data-src="5.jpg" /> <img data-src="6.jpg" />
|
一、 监听滚动事件,判断图片与视口的高度差来重置图片的src
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
| const imgs = document.querySelectorAll('img');
function lazyLoad(){ imgs.forEach( (img) => { const imageTop = img.getBoundingClientRect().top; if(imageTop < window.innerHeight){ const data_src = img.getAttribute('data-src'); img.setAttribute('src', data_src) } }) }
function debounce(fn, delay = 500) { let timer = null; return function (...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.call(this, args); }, delay); }; }
window.addEventListener('scroll', debounce(lazyLoad, 600))
|
缺点:
- 屏幕滚动的时候会不断触发滚动事件
- 图片加载完成之后,当触发滚动事件,还会不断更新src的值
二、 IntersectionObserver()方法监听或取消监听图片
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
| const imgs = document.querySelectorAll('img');
const callback = ( entries ) => { console.log( entries ); entries.forEach( entry => { if (entry.isIntersecting) { const img = entry.target; const data_src = img.getAttribute('data-src'); img.setAttribute('src', data_src); observer.unobserve(img); console.log('666'); } }) }
const observer = new IntersectionObserver( callback );
imgs.forEach( img => { observer.observe(img) })
|
缺点:
- 兼容性 不支持ie
优点:
- 每个懒加载图片只加载一次