我们通过js监听页面的滚动也能实现。
使用js实现的原理主要是判断当前图片是否到了可视区域:
-
拿到所有的图片 dom 。
-
遍历每个图片判断当前图片是否到了可视区范围内。
-
如果到了就设置图片的 src 属性。
-
绑定 window 的 scroll 事件,对其进行事件监听。
在页面初始化的时候,图片的src实际上是放在data-src属性上的,当元素处于可视范围内的时候,就把data-src赋值给src属性,完成图片加载。
下面展示一个demo:
Lazyload img { display: block; margin-bottom: 50px; height: 200px; width: 400px; }
先获取所有图片的 dom,通过 document.body.clientHeight 获取可视区高度,再使用 element.getBoundingClientRect() API 直接得到元素相对浏览的 top 值, 遍历每个图片判断当前图片是否到了可视区范围内。代码如下:
function lazyload() {
let viewHeight = document.body.clientHeight //获取可视区高度
let imgs = document.querySelectorAll('img[data-src]')
imgs.forEach((item, index) => {
if (item.dataset.src === '') return
// 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
let rect = item.getBoundingClientRect()
if (rect.bottom >= 0 && rect.top < viewHeight) {
item.src = item.dataset.src
item.removeAttribute('data-src')
}
})
}
最后给 window 绑定 onscroll 事件
主要就完成了一个图片懒加载的操作了。但是这样存在较大的性能问题,因为 scroll 事件会在很短的时间内触发很多次,严重影响页面性能,为了提高网页性能,我们需要一个节流函数来控制函数的多次触发,在一段时间内(如 200ms)只执行一次回调。
下面实现一个节流函数
function throttle(fn, delay) {
let timer
let prevTime
return function (...args) {
const currTime = Date.now()
const context = this
if (!prevTime) prevTime = currTime
clearTimeout(timer)
if (currTime - prevTime > delay) {
prevTime = currTime
fn.apply(context, args)
clearTimeout(timer)
return
}
timer = setTimeout(function () {
prevTime = Date.now()
timer = null
fn.apply(context, args)
}, delay)
}
}
window.addEventListener('scroll', throttle(lazyload, 200))
通过上面例子的实现,我们要实现懒加载都需要去监听 scroll 事件,尽管我们可以通过函数节流的方式来阻止高频率的执行函数,但是我们还是需要去计算 scrollTop,offsetHeight 等属性,有没有简单的不需要计算这些属性的方式呢,答案就是 IntersectionObserver。
IntersectionObserver 是一个比较新的 API,可以自动"观察"元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。我们来看一下它的用法:
var io = new IntersectionObserver(callback, option)
// 开始观察
io.observe(document.getElementById('example'))
// 停止观察
io.unobserve(element)
// 关闭观察器
io.disconnect()
总结
三套“算法宝典”
算法刷题LeetCode中文版(为例)
人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。
最后,我想说的是,无论你现在什么年龄,位于什么城市,拥有什么背景或学历,跟你比较的人永远都是你自己,所以明年的你看看与今年的你是否有差距,不想做咸鱼的人,只能用尽全力去跳跃。祝愿,明年的你会更好!