原生js - 两种图片懒加载实现原理
目前图片懒加载的方式主要有两种:
1、利用getBoundingClientRectAPI得到当前元素与视窗的距离来判断
2、利用h5的新API IntersectionObserver 来实现
getBoundingClientRect
Element.getBoundingClientRect() 方法返回值是一个 DOMRect 对象,包含了该元素一组矩形的集合:是与该元素相关的css边框集合(top, left, right, bottom)。
我们可以采用如下方法来判断是否在可视区域:
isViewport (el) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
let { top, left, right, bottom } = el.getBoundingClientRect()
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
)
}
getBoundingClientRect 方式来实现需要监听 scroll 方法来配合,对于浏览器的性能会有一定的问题。
IntersectionObserver
属性
root: 所监听对象的具体祖先元素。如果未传入值或值为null,则默认使用顶级文档的视窗。
rootMargin: 计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要。
thresholds: 可以是一个单独的number,也可以是一个number数组。当 root 元素与 target 元素相交达到该值的时候会执行回调。当值设定为0时,那么 target 元素有一个像素出现在 root 元素,回调就会执行;如果值设为1,那么就是当 target 元素完全出现在 root 元素当中才会执行。默认为0。如果当值设定为 [0, 0.25, 0.5, 0.75, 1] 时,那么每满足一个值就会回调一次。该值设定的时候不是复数,当取值的时候为复数:
var observer = new IntersectionObserver(_observer, {
root : null,
threshold: [] // 单数
});
observer.thresholds // 复数
方法
IntersectionObserver.disconnect: 停止所有监听工作
IntersectionObserver.observe: 开始监听一个目标元素
IntersectionObserver.takeRecords: 返回所有观察目标对象的数组
IntersectionObserver.unobserve: 停止监听特定目标元素。
function LazyLoad (config) {
this.default = {
root: null,
threshold: 0
}
this.settings = Object.assign(this.default, config)
this.images = []
this.observer = null
this.init()
}
LazyLoad.prototype = {
init () {
if (!window.IntersectionObserver) {
this.loadImages()
return
}
this.images = document.querySelectorAll(this.settings.selector || '[data-src]')
let _this = this
let observeConfig = {
root: this.settings.root,
rootMargin: this.settings.rootMargin,
threshold: [this.settings.threshold]
}
this.observer = new IntersectionObserver(changes => {
Array.prototype.forEach.call(changes, entry => {
if (entry.isIntersecting) {
let target = entry.target
_this.observer.unobserve(target)
let src = target.dataset.src
if (target.tagName.toLowerCase() === 'img') {
target.src = src
} else {
target.style.backgroundImage = `url(${src})`
}
target.removeAttribute('data-src')
}
})
}, observeConfig)
Array.prototype.forEach.call(this.images, image => {
_this.observer.observe(image)
image.src = _this.settings.placeholder
})
},
loadImages () {
let _this = this
_this.replaceSrc()
let hasDone = false
function _scroll() {
if (hasDone) return
hasDone = true
setTimeout(() => {
_this.replaceSrc()
hasDone = false
}, 100)
}
window.onscroll = _scroll
},
replaceSrc () {
let _this = this
let imgs = document.querySelectorAll(this.settings.selector || '[data-src]')
Array.prototype.forEach.call(imgs, image => {
if (!image.src) image.src = _this.settings.placeholder
let src = image.dataset.src
if (_this.isInnerView(image)) {
if (image.tagName.toLowerCase() === 'img') {
image.src = src
} else {
image.style.backgroundImage = `url(${src})`
}
image.removeAttribute('data-src')
}
})
},
isInnerView (el) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
let { top, left, right, bottom } = el.getBoundingClientRect()
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
)
},
destroy () {
this.observer.disconnect();
}
}
原生js - 两种图片懒加载实现原理的更多相关文章
- js可视区域图片懒加载
可视区域图片懒加载 实现原理,页面滚动时获取需要懒加载的图片,判断此图片是否在可视区域内,是则设置图片data-src地址为src地址,加载图片. html下载地址 <!DOCTYPE html ...
- js实现网页图片延时加载的原理和代码 提高网站打开速度
有时我们看到一些大型网站,页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片则不加载,一定程序上加快了页面加载的速度,对 ...
- 前端实现图片懒加载(lazyload)的两种方式
在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽.这也就是们通 ...
- JS图片懒加载
简介 当页面图片太多时,加载速度就会很慢.尤其是用2G/3G/4G访问页面,不仅页面慢,而且还会用掉很多流量.图片懒加载的原理就是将页面内所有需要加载的图片全部换成一张默认的图片(一般尺寸很小),只有 ...
- 图片懒加载--lazyload.js的用法
这几天公司的项目已经完成的差不多了,只剩下各种优化问题.今天着重于图片加载的优化.当一个页面需要下拉很长而且又有过多的图片要加载时,就会发生很多http请求,就会拉慢网页加载速度,用户体验不友好.怎么 ...
- Vue图片懒加载
图片懒加载的原理 先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src).当js监听到该图片元素进入可视窗口时,即将自定义属性 ...
- 使用jQuery实现图片懒加载原理
原文:https://www.liaoxuefeng.com/article/00151045553343934ba3bb4ed684623b1bf00488231d88d000 在网页中,常常需要用 ...
- 页面性能优化-原生JS实现图片懒加载
在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...
- 原生js开发,无依赖、轻量级的现代浏览器图片懒加载插件,适合在移动端开发使用
优势 1.原生js开发,不依赖任何框架或库 2.支持将各种宽高不一致的图片,自动剪切成默认图片的宽高 比如说你的默认图片是一张正方形的图片,则各种宽度高度不一样的图片,自动剪切成正方形. 完美解决移动 ...
随机推荐
- 获取本机IP,本机名称
InetAddress addr = InetAddress.getLocalHost(); ip=addr.getHostAddress().toString;//获得本机IP address=ad ...
- thinkphp 配置参考
惯例配置 应用设定 'APP_USE_NAMESPACE' => true, // 应用类库是否使用命名空间 3.2.1新增 'APP_SUB_DOMAIN_DEPLOY' => fals ...
- bzoj1047题解
[解题思路] (p.s.:刚看的时候一脸懵逼..没看见N已经给定了,还以为要用某些高明的方法..果然还是太naive了..) 两遍预处理,第一遍处理出f[i][j][0/1]表示第i行从j-n+1~j ...
- 状态压缩dp增量统计贡献——cf1238E(好题)
这题的状态设计非常巧妙,因为dp[S]表示的并非当前正确的值,而是维护一个中间量,这个中间量在到达末状态时才正确 当然官方的题解其实更加直观,只不过理解起来其实有点困难 /* 给定一个串s,字符集为2 ...
- Shell基础(六):使用awk提取文本、awk处理条件、awk综合脚本应用、awk流程控制、awk扩展应用
一.使用awk提取文本 目标: 本案例要求使用awk工具完成下列过滤任务: 1> 练习awk工具的基本用法 2> 提取本机的IP地址.根分区使用率 3> 格式化输出/et ...
- 使用Nodejs 的http-proxy 模块做代理服务器的尝试
参考 : https://blog.csdn.net/zhihuoqian9683/article/details/78944482 (亲测可行) http://www.mizuiren.com/4 ...
- css 导航样式
html 结构 <div class="nav-menu float-r"> <ul class="menu-item"> <l ...
- C++——Struct 和 Union区别
1.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而Union每个成员会用同一个存储空间,只能存储最后一个成员的信息. 2.都是由多个不同的 ...
- 3. Python基础语法
注释 我们在文言文中经常会看到注释,注释可以帮助读者对文章的理解.代码中的注释也是一样,优秀的代码注释可以帮助读者对代码的理解.当然在代码编写过程中,注释的使用不一定只是描述一段代码,也可能的是对代码 ...
- Nginx 配置参数
1 Proxy_send_timeout 定义后端在多久的时间内必须返回完所有的数据给Nginx. 2 Proxy_read_timeout