We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
这个方案是借助滚动距离来判断的,获取document.documentElement的scrollTop与需要懒加载的图片标签的offsetTop进行比较,看图片是否进入可视区域,从而实现图片加载。
代码如下:
// 封装一个获取图片到顶部的距离 function getTop(elm){ let tempTop = elm.offsetTop; //如果包裹img的父元素离顶部也有距离,那么也要把它加上 while(elm = elm.offsetParent) { //注意这儿offsetParent返回的是元素不是数值,同时这儿是赋值语句 tempTop += elm.offsetTop; } return tempTop; } function lazyLoad(imgs){ //获取可视区域高度 let viewHeight = document.documentElement.clientHeight || window.innerHeight; //获取滚动高度 let scrollTopVal = document.documentElement.scrollTop || document.body.scrollTop; for(var i = 0; i < imgs.length; i++){ if((viewHeight + scrollTopVal) > getTop(imgs[i])){ imgs[i].src = imgs[i].getAttribute('data-src') } } } // 使用 // 给你需要懒加载的图片设置一个类名'lazy-load' let imgs = document.querySelectorAll('.lazy-load'); lazyLoad(imgs); // 进行滚动监听 window.onscroll = function() { lazyLoad(imgList); }
浏览器自带的API IntersectionObserver进行检测,十分方便
先贴上代码实现:
// 给你需要懒加载的图片设置一个类名'lazy-load' let imgs = document.querySelectorAll('.lazy-load'); // 实例化一个交叉观察者对象 let obsever = new IntersectionObserver((entries) => { entries.forEach((item, index, arrSelf) => { // 判断检测的对象是否进入可视窗口 if(item.isIntersecting) { // 进入后进行图片地址赋值 item.target.src = item.target.dataset.src; // 实现图片加载后不在进行检测 obsever.unobserve(item.target); } }); }); // 注册观察需要懒加载的img imgs.forEach((item) => { obsever.observe(item); });
用法
new IntersectionObserver(callback, options);
new IntersectionObserver((entries) => { }, { // options参数 });
entries当前已监听并且发生了交叉的目标集合,我们可以把它用来循环,entres的打印结果如下:
参数表,对于entries这个集合里面的每个对象都有如下常用的参数:
| 属性 | 说明 | | - | - | - | | boundingClientReact | 元素的空间信息,就是位置信息这些个 | | intersctionRatio | 元素可见区域的占比 | | isInterscting | 判断元素是否交叉,也就是元素在可视区是否可见了 | | target | 目标节点,跟我们使用事件的event.target效果一样 |
| 属性 | 说明 | | - | - | - | | root | 指定父元素,默认为视窗 | | rootMargin | 触发交叉的偏移值,默认为"0px 0px 0px 0px"。(上左下右,正数为向外扩散,负数则向内收缩) |
| 名称 | 说明 | 参数 | | - | - | - | - | | observe | 开始监听一个目标元素 | DOM节点 | | unobserve | 停止监听一个目标元素 | DOM节点 | | takeRecords | 返回所有监听的目标元素集合 | | | disconnect | 停止监听所有元素 | |
IntersectionObserve这个API用起来确实方便,但是还是有一部分浏览器不支持,所以需要封装判断下。
function getTop(elm){ let tempTop = elm.offsetTop; //如果包裹img的父元素离顶部也有距离,那么也要把它加上 while(elm = elm.offsetParent) { //注意这儿offsetParent返回的是元素不是数值,同时这儿是赋值语句 tempTop += elm.offsetTop; } return tempTop; } function lazyLoad(imgs){ //获取可视区域高度 let viewHeight = document.documentElement.clientHeight; //获取滚动高度 let scrollTopVal = document.documentElement.scrollTop || document.body.scrollTop; console.log(viewHeight, scrollTopVal) for(var i = 0; i < imgs.length; i++){ if((viewHeight + scrollTopVal) > getTop(imgs[i])){ imgs[i].src = imgs[i].getAttribute('data-src') } } } function useIntersectionObserve(imgList) { let obsever = new IntersectionObserver((entries) => { entries.forEach((item, index, arrSelf) => { console.log(entries) if(item.isIntersecting) { item.target.src = item.target.dataset.src; obsever.unobserve(item.target); } }); }); imgList.forEach((item) => { obsever.observe(item); }); } export default { // 这两个个方案要求img标签有默认的高度,不然当一个页面出来就展示图片的情况下会一下展示很多图片, // 所以在使用懒加载方案时给img加默认高度 // 单独使用普通懒加载方案 lazyloadDefault(selector) { let imgList = document.querySelectorAll(selector); lazyLoad(imgList); window.onscroll = function() { lazyLoad(imgList); } }, // 单独使用IntersectionObserve lazyLoadIntersectionObserver(selector) { let imgList = document.querySelectorAll(selector); let obsever = new IntersectionObserver((entries) => { entries.forEach((item, index, arrSelf) => { console.log(entries) if(item.isIntersecting) { item.target.src = item.target.dataset.src; obsever.unobserve(item.target); } }); }); imgList.forEach((item) => { obsever.observe(item); }); }, // 多浏览器适配方案 lazyLoadPolyfill(selector) { let imgList = document.querySelectorAll(selector); if(!window.IntersectionObserver) { lazyLoad(imgList); window.onscroll = function() { lazyLoad(imgList); } }else { useIntersectionObserve(imgList) } } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
常见的懒加载方案
这个方案是借助滚动距离来判断的,获取document.documentElement的scrollTop与需要懒加载的图片标签的offsetTop进行比较,看图片是否进入可视区域,从而实现图片加载。
代码如下:
使用交叉观察者实现懒加载
浏览器自带的API IntersectionObserver进行检测,十分方便
先贴上代码实现:
IntersectionObserver
用法
entries当前已监听并且发生了交叉的目标集合,我们可以把它用来循环,entres的打印结果如下:
参数表,对于entries这个集合里面的每个对象都有如下常用的参数:
| 属性 | 说明 |
| - | - | - |
| boundingClientReact | 元素的空间信息,就是位置信息这些个 |
| intersctionRatio | 元素可见区域的占比 |
| isInterscting | 判断元素是否交叉,也就是元素在可视区是否可见了 |
| target | 目标节点,跟我们使用事件的event.target效果一样 |
| 属性 | 说明 |
| - | - | - |
| root | 指定父元素,默认为视窗 |
| rootMargin | 触发交叉的偏移值,默认为"0px 0px 0px 0px"。(上左下右,正数为向外扩散,负数则向内收缩) |
| 名称 | 说明 | 参数 |
| - | - | - | - |
| observe | 开始监听一个目标元素 | DOM节点 |
| unobserve | 停止监听一个目标元素 | DOM节点 |
| takeRecords | 返回所有监听的目标元素集合 | |
| disconnect | 停止监听所有元素 | |
封装一个支持多浏览器的懒加载方案
IntersectionObserve这个API用起来确实方便,但是还是有一部分浏览器不支持,所以需要封装判断下。
The text was updated successfully, but these errors were encountered: