图片加载概念引入
图片赖加载和图片预加载
图片预加载: 提前加载图片,当用户需要时,直接从缓存中渲染
图片赖加载: 懒加载主要是作为服务器前端优化。减少请求数或延迟请求数
懒加载实现原理
img的src属性用来表示图片的url。当src属性不为空时,就会向浏览器发送请求。那我们可以将真实地址存在一个自定义属性data-src中,当页面滚动时,将可视区域的图片的src值赋为真实的值。
实现的几种方式
- scrollTop(网页被卷去的高) + clientHeight(网页可视区域的高) > offsetTop(元素到offsetParent顶部的距离)
- el.getBoundingClientRect().top <= window.innerHeight
- IntersectionObserver(IE不支持)
代码实现
<!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
src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg" />
<img src="https://media-coa.feihe.com/coa/0/db0080e0-96cb-4eee-a5b3-ca0fdbf9bda6.png" />
<img
src="https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=151472226,3497652000&fm=26&gp=0.jpg" />
<img
src="https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3892521478,1695688217&fm=26&gp=0.jpg" />
<img
src="https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg" />
<img
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>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)