1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 图片懒加载(lazyload)的几种方式

图片懒加载(lazyload)的几种方式

时间:2020-02-25 08:46:52

相关推荐

图片懒加载(lazyload)的几种方式

背景

当页面中有很多图片时,全部加载需要很多时间,而且会消耗很多渲染资源,为了解决这个问题,加强用户体验,我们先将看得到的区域中的图片加载,也就是可视化区域加载,剩余部分等之后再加载。

原理

一个图片就是一个<img>标签,浏览器会根据<img>标签的src属性来发起请求,只要我们不给src赋值,或者赋值一个很小的加载图片,使用一个暂时的属性来保存图片的src,比如data-src(可以用其他的名字,只要不会发送http请求就行),当图片进入可视化区域后,再把data-src赋值给src。

示例

<img data-src="@/assets/imgs/test.jpg" src="@/assets/imgs/login.jpg">

1.e.offsetTop

e代表图片元素,判断图片是否进入可视区域

e.offsetTop < document.body.clientHeight + document.body.scrollTop

data(){return{flag: true}},created() {this.throttle(this.lazyLoad, 3000)() //首次进入加载},mounted() {const that = this;window.addEventListener('scroll',()=>{that.throttle(that.lazyLoad, 2000)()})},methods:{//节流优化throttle(fn, delay){const that = this;return function () {if (!that.flag) return;that.flag = false; //没执行过就一直是false,会直接returnsetTimeout(() => {fn.apply(that, arguments);that.flag = true; //setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环。当定时器回调函数没有执行的时候标记永远是false,在开头被return掉,从而达到回流效果}, delay);}},lazyLoad(){let images = document.getElementsByTagName('img') //加定时器的目的是为了让images能够遍历到setTimeout(()=>{for(let i =0;i<images.length;i++){if(images[i].offsetTop<document.body.clientHeight + document.body.scrollTop){ images[i].src = images[i].dataset.src;}}},300)}}

2.e.getBoundingRect

e.getBoundingClientRect()方法返回一个DOMRect对象,其提供了元素的大小及其相对于视口的位置。与offsetTop方法类似,只是改变了判断图片元素是否在可视区域的计算方式。

e.getBoundingClientRect().top<document.body.clientHeight

data(){return{flag: true}},created() {this.throttle(this.lazyLoad, 3000)() //首次进入加载},mounted() {const that = this;window.addEventListener('scroll',()=>{that.throttle(that.lazyLoad, 2000)()})},methods:{//节流优化throttle(fn, delay){const that = this;return function () {if (!that.flag) return;that.flag = false; //没执行过就一直是false,会直接returnsetTimeout(() => {fn.apply(that, arguments);that.flag = true; //setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环。当定时器回调函数没有执行的时候标记永远是false,在开头被return掉,从而达到回流效果}, delay);}},lazyLoad(){let images = document.getElementsByTagName('img')//加定时器的目的是为了让images能够遍历到setTimeout(()=>{for(let i =0;i<images.length;i++){if(images[i].getBoundingClientRect().top<document.body.clientHeight){ //getBoundingClientRect().top 元素的上边相对浏览器视窗的位置如果小于可视窗口的高度images[i].src = images[i].dataset.src;}}},300)}}

3.IntersectionObserver

交叉观察器,自动观察指定对象是否进入可视区域

let observe = new IntersectionObserver(callback, option);

created() {this.intersectionObserver();},methods:{intersectionObserver(){let images = document.getElementsByTagName('img');const observer = new IntersectionObserver((imgs) => {console.log('imgs===', imgs)// imgs: 目标元素集合imgs.forEach((img) => {// img.isIntersecting代表目标元素可见,可见的时候给src赋值if (img.isIntersecting) {const item = img.targetitem.src = item.dataset.src//解除对img元素的观察observer.unobserve(item);}})})//定时器和Array.from的目的是让images可遍历setTimeout(()=>{Array.from(images).forEach(item => {//观察img元素observer.observe(item);})},300)}}

4.vue-lazyload库

(1)安装

npm install vue-lazyload -S

(2)全局引用并使用

import VueLazyload from 'vue-lazyload'Vue.use(VueLazyload)

(3)使用

将:src='xxx'改成 vue-lazy='xxx'

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。