1. dataset
HTML5
中我们可以使用data-
前缀设置我们需要的自定义属性,来进行一些数据的存放。dataset
自定义属性的格式:data-xx
;前面的data-
是固定的,后面的xx
一般为表示与自定义属性相关的字符串。img
标签中的data-src
属性就属于一种自定义的dataset
属性。
举个例子:
<div id="today"
data-food="sushi"
data-meal="lunch">dinner</div>
而当我们想要获取这个属性时:
var today = document.getElementById('today');
var typeOfFood = today.dataset.food;
参考文献:https://www.zhangxinxu.com/wordpress/2011/06/html5自定义属性对象dataset简介/
2. 懒加载
页面中的img
元素,如果没有src
属性,浏览器就不会发出请求去下载图片,只有通过javascript
设置了图片路径,浏览器才会发送请求。所以懒加载基本的原理就是用dataset
自定义属性取代src
存储图片的路径,然后在检测到图片进入到可视区域的时候,再将其换为src
。那我们就来基本实现一下吧。
- 基本布局
首先将所有图片的src
换为自定义属性data-src
,这个时候图片是不显示的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>懒加载</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
height: 600px;
box-sizing: border-box;
border: 1px solid black;
}
img {
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<div id="box">
<ul>
<li>
<img data-src="./图片懒加载/1.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/2.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/3.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/4.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/5.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/6.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/7.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/8.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/9.jpg" alt="">
</li>
<li>
<img data-src="./图片懒加载/10.jpg" alt="">
</li>
</ul>
</div>
</body>
</html>
- 判断条件
window.innerHeight
可以获取到这个窗口的高度(不包括工具栏和滚动条)。getBoundingClientRect()
方法用来获取页面中某个元素的左、上、右、下分别相对浏览器视窗的位置,返回的是一个矩形对象,包括四个属性,分别是left 、top、right、bottom。分别表示元素各边与页面上边和左边的距离。
基本的判断就是如果该图片距离窗口上方的位置小于窗口的高度(也就是说该图片已经进入了窗口),那么就将该图片的src
属性赋为data-src
找那个存的图片路径。
然后全局绑定scroll
事件,在滚动页面的时候,图片进入到窗口后,500ms
之后才会显示出图片。
<script>
function imgonload() {
let img = document.querySelectorAll("img");
/*console.log(img);*/
for(let i=0; i<img.length; i++) {
if(img[i].getBoundingClientRect().top < window.innerHeight) {
//图片一旦有src就会加载出来,所以图片的路径不会放在src中,而是一个自定义的属性data-src中
img[i].src = img[i].dataset.src;
}
}
}
function scollImg(fn) {
let timer = null;
let context = this;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context);
}, 500)
}
}
window.onload = imgonload;
window.onscroll = scollImg(imgonload);
</script>
这样就完后了一个懒加载图片的效果了。
3. 占位图
这样的懒加载图片的效果还不是很明显,我们通常会用一张占位图来显示该区域有图片即将加载出来(loading.gif
),将所有图片的src
设为占位图标,然后在滚动的时候图片进入可视区域src
就会被替换成data-src
中存的图片路径。完整的代码为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>懒加载</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
height: 600px;
box-sizing: border-box;
border: 1px solid black;
}
img {
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<div id="box">
<ul>
<li>
<img data-src="./图片懒加载/1.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/2.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/3.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/4.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/5.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/6.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/7.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/8.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/9.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/10.jpg" alt="">
</li>
</ul>
</div>
<script>
function imgonload() {
let img = document.querySelectorAll("img");
/*console.log(img);*/
for(let i=0; i<img.length; i++) {
if(img[i].getBoundingClientRect().top < window.innerHeight) {
//图片一旦有src就会加载出来,所以图片的路径不会放在src中,而是一个自定义的属性data-src中
img[i].src = img[i].dataset.src;
}
}
}
function scollImg(fn) {
let timer = null;
let context = this;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context);
}, 500)
}
}
window.onload = imgonload;
window.onscroll = scollImg(imgonload);
</script>
</body>
</html>