This is a Lengux blog.

We sat and drank with the sun on our shoulders and felt like free men. We could have been tarring the roof of one of our own houses. We were the lords of all creation. As for Andy,he spent that break hunkered in the shade,a strange little smile on his face,watching us drink his beer.

图片懒加载和图片预加载

图片懒加载和图片预加载

图片赖加载懒加载主要是作为服务器前端优化。减少请求数或延迟请求数

图片预加载 提前加载图片,当用户需要时,直接从缓存中渲染

懒加载实现原理:

img的src属性用来表示图片的url。当src属性不为空时,就会向浏览器发送请求。那我们可以将真实地址存在一个自定义属性data-src中,当页面滚动时,将可视区域的图片的src值赋为真实的值。

实现的几种方式

  1. scrollTop(网页被卷去的高) + clientHeight(网页可视区域的高) > offsetTop(元素到offsetParent顶部的距离)

  2. el.getBoundingClientRect().top <= window.innerHeight

  3. IntersectionObserver(IE不支持)

    代码实现:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title></title>
<!--适应移动端-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--css样式-->
<style>
body {
background-color: #EBEBEB
}

.aaa {
background-color: #CB4F51;
padding: 10px;
display: block
}

img {
background: #F1F1FA;
width: 375px;
height: 450px;
display: block;
margin: 10px auto;
border: 0;
}
</style>

</head>

<body>


<div>
<img
data-src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&amp;fm=26&amp;gp=0.jpg" />
<img data-src="https://media-coa.feihe.com/coa/0/db0080e0-96cb-4eee-a5b3-ca0fdbf9bda6.png" />
<img
data-src="https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=151472226,3497652000&fm=26&gp=0.jpg" />
<img
data-src="https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3892521478,1695688217&fm=26&gp=0.jpg" />
<img
data-src="https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg" />
<img
data-src="https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1776601493,3966748998&fm=26&gp=0.jpg" />
</div>

<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var imgs = document.querySelectorAll('img');
function throttle(func, wait) { // 节流实现
let timer
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
func(...args)
timer = null
}, wait);
}
}
}
// 方法1: H + S > offsetTop
// 1. offsetTop:元素到offsetParent顶部的距离
// 2. offsetParent:距离元素最近的一个具有定位的祖宗元素(relative,absolute,fixed),若祖宗都不符合条件,offsetParent为body。
// 网页被卷去的高: document.body.scrollTop;
// 网页可见区域高: document.body.clientHeight;
function lazyLoad1(imgs) {
let S = document.documentElement.scrollTop || document.body.scrollTop
let H = document.documentElement.clientHeight
Array.from(imgs).forEach(img => {
if (S + H > img.offsetTop && !img.src) { //如果此时图片在可视区域,并且src没有数据
img.src = img.dataset.src // 将自定义属性赋值给src
}
});
}
// 方法2: el.getBoundingClientRect.top <= window.innerHeight
// getBoundingClientRect: 该对象提供有关元素大小及其相对于视口的位置的信息。集合中有top, right, bottom, left等属性
// window.innerHeight:返回窗口的文档显示区的高度
function lazyLoad2(imgs) {
function getBoolean(img) {
let bound = img.getBoundingClientRect()
let H = window.innerHeight
return bound.top < H
} // 封装返回值
Array.from(imgs).forEach((img) => {
if (getBoolean(img) && !img.src) {
img.src = img.dataset.src
}
})
}
// 方法三
// 方法3:IntersectionObserver(IE不支持)
function lazyLoad3(imgs) {
const io = new IntersectionObserver(
(changes) => {
console.log('changes', changes)
changes.forEach((change) => {
console.log('change', change)

var img = change.target;
// intersectionRatio 完全可见时为1
if (change.intersectionRatio > 0) {
if (!img.src) {
img.src = img.dataset.src;
}
}
img.onload = img.onerror = () => io.unobserve(img);
})
}
)
imgs.forEach((img) => io.observe(img))
}
// lazyLoad3(imgs);
// let throttleLazyLoad1 = throttle(lazyLoad1, 200) // 方法1节流实现
let throttleLazyLoad2 = throttle(lazyLoad2, 200) // 方法2节流实现

window.onload = window.onscroll = function () {
// throttleLazyLoad1(imgs)
throttleLazyLoad2(imgs)
}
//window.innerHeight属于BOM(浏览器对象模型),获取的高度包含横向滚动条

// document.documentElement.clientHeight属于文档对象模型,不包含横向滚动条

// document.body.clientHeight属于文档对象模型,body高度,如果设置body height=100%,document.documentElement.clientHeight=document.body.clientHeight
})
</script>

</body>

</html>
user@ui-verse:~$
Hey!

In the sea of coding, I am Lengux, pursuing creativity and user experience.

 友情链接
 标签
Made with 💛 by Lengux and some fantastic contributors! hexo blog framework
豫ICP备2022014432号-1