Open cleverMountain opened 1 year ago
2.实现图片懒加载
<head>
<style>
.img {
width: 200px;
height: 200px;
background-color: gray;
margin-bottom: 20px;
}
.pic {
width: 100%;
height: 100%;
}
</style>
</head>
<!-- 图片来自网络,侵删。 -->
<body>
<div class="container">
<div class="img">
<!-- 注意我们并没有为它引入真实的src -->
<img class="pic" alt="加载中"
data-src="https://tse1-mm.cn.bing.net/th/id/OIP.8OrEFn_rKe82kqAWFjTuMwHaEo?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://ssl.tzoo-img.com/images/tzoo.94911.0.910013.seoul-nami.jpg?width=1080" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.ZitgAuABnwkrGn4lid2ZmQHaEK?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="http://pic34.photophoto.cn/20150315/0034034862056002_b.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="http://img.mp.sohu.com/upload/20170724/32d4409f34194b029ed287abf1c99b70_th.png" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075991913520.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.PZdPKj3sXEX2jLrepx3MUwHaEo?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075831439349.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075468043336.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse2-mm.cn.bing.net/th/id/OIP.CRYz5Bv4vylsMh83G4CsLgHaFj?pid=Api&rs=1" />
</div>
</div>
<script>
let options = {
root: null,
rootMargin: '0px',
threshold: 1 // 完整出现触发
}
let callback = (entries, observer) => {
debugger
entries.forEach(entry => {
// 元素像素点出现50%时触发
console.log(entry.intersectionRatio)
if (entry.intersectionRatio > 0.5) {
entry.target.setAttribute('src', entry.target.getAttribute('data-src'))
}
})
}
let observer = new IntersectionObserver(callback, options);
let target = document.getElementsByClassName('pic')
// 给每一个图片添加观测者
Array.prototype.forEach.call(target, (item) => {
observer.observe(item)
})
</script>
</body>
3.其它测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
background-color: rgba(40, 40, 190, 255);
border: 4px solid rgb(20, 20, 120);
transition: background-color 1s, border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.vertical {
color: white;
font: 32px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(20, 20, 120);
text-align: center;
padding: 20px;
}
.li {
margin-top: 500px;
}
</style>
</head>
<body>
<div class="li">da</div>
<div class="li">da</div>
<divc lass="li">da</div>
<div id="box">
<div class="vertical">
Welcome to <strong>The Box!</strong>
</div>
</div>
<script>
function createObserver() {
let observer;
let options = {
root: null,
rootMargin: "0px",
// 默认值是 0 (意味着只要有一个 target 像素出现在 root 元素中,回调函数将会被执行)。
// 该值为 1.0 含义是当 target 完全出现在 root 元素中时候 回调才会被执行。
// target 在 root 元素中中的可见性每超过 0.1 或者减少 0.1 的时候都通知一次
threshold: buildThresholdList() // [0,0.1, 0.2]数组,有几个触发几次 0-0.1触发一次 0.1-0.2再触发一次
};
observer = new IntersectionObserver(handleIntersect, options);
observer.observe(boxElement);
}
function buildThresholdList() {
let thresholds = [];
let numSteps = 20;
// thresholds.push(0);
for (let i = 1; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
// 触发次数
console.log(thresholds)
return thresholds;
}
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
// intersectionRatio: 当前元素占比视口多少
// target: 目标元素
if (entry.intersectionRatio > prevRatio) {
console.log(entry)
// 透明度0-1
entry.target.style.backgroundColor = increasingColor.replace("ratio", entry.intersectionRatio);
} else {
entry.target.style.backgroundColor = decreasingColor.replace("ratio", entry.intersectionRatio);
}
prevRatio = entry.intersectionRatio;
console.log(prevRatio)
});
}
const numSteps = 20.0;
let boxElement;
let prevRatio = 0.0;
// 添加透明度
let increasingColor = "rgba(40, 40, 190, ratio)";
let decreasingColor = "rgba(190, 40, 40, ratio)";
// Set things up
window.addEventListener("load", (event) => {
boxElement = document.querySelector("#box");
createObserver();
}, false);
</script>
</body>
</html>
4.图片懒加载传统方式实现
<head>
<style>
.img {
width: 200px;
height: 200px;
background-color: gray;
margin-bottom: 20px;
}
.pic {
width: 100%;
height: 100%;
}
</style>
</head>
<!-- 图片来自网络,侵删。 -->
<body>
<div class="container">
<div class="img">
<!-- 注意我们并没有为它引入真实的src -->
<img class="pic" alt="加载中"
data-src="https://tse1-mm.cn.bing.net/th/id/OIP.8OrEFn_rKe82kqAWFjTuMwHaEo?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://ssl.tzoo-img.com/images/tzoo.94911.0.910013.seoul-nami.jpg?width=1080" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.ZitgAuABnwkrGn4lid2ZmQHaEK?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="http://pic34.photophoto.cn/20150315/0034034862056002_b.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="http://img.mp.sohu.com/upload/20170724/32d4409f34194b029ed287abf1c99b70_th.png" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075991913520.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.PZdPKj3sXEX2jLrepx3MUwHaEo?pid=Api&rs=1" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075831439349.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中" data-src="https://pic6.wed114.cn/20180829/2018082910075468043336.jpg" />
</div>
<div class="img">
<img class="pic" alt="加载中"
data-src="https://tse2-mm.cn.bing.net/th/id/OIP.CRYz5Bv4vylsMh83G4CsLgHaFj?pid=Api&rs=1" />
</div>
</div>
<script>
let images = document.getElementsByClassName('pic')
// 获取视口高度
const viewportHeight = document.body.clientHeight || document.documentElement.clientHeight
const show = () => {
console.log(1)
Array.prototype.forEach.call(images, (item) => {
console.log(item.getBoundingClientRect().top)
if (viewportHeight - item.getBoundingClientRect().top > 0) {
item.src = item.getAttribute('data-src')
}
})
}
function debounce(func, wait) {
let timer = null
return function () {
let args = arguments
timer && clearTimeout(timer)
timer = setTimeout(() => {
func.call(this, ...args)
}, wait)
}
}
window.onload = show()
window.addEventListener('mousewheel', debounce(show, 600), false);
</script>
</body>
5.getBoundingClientRect,法返回一个 [DOMRect] 对象,其提供了元素的大小及其相对于[视口]的位置。top:距离视口的高度 left botom right
1.提供了一种异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(root) 语法
callback:当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数(entries:目标元素集合, observer:实例) options:配置 observer 实例的对象。如果options未指定,observer 实例默认使用文档视口作为 root,并且没有 margin,阈值为 0%。接收三个参数(root:祖先元素,rootMargin,threshold:目标元素与父元素交叉值)