图片的加载是由src引起的,给src赋值,浏览器请求图片资源。
使用HTML5的data-xxx属性存储图片路径,需要时赋值给src。
思路一:
图片加载条件:
imgs.offsetTop(元素到顶部距离) < window.innerHeight(浏览器可视区高度)
+ document.body.scrollTop(滚动距离)
思路二:
检测图片进入浏览器可视区的时候加载图片
<!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>
.viewport {
width: 300px;
height: 200px;
border: 1px solid blue;
overflow: auto;
}
.box1 {
height: 600px;
width: 100%;
}
.observed {
width: 100px;
height: 100px;
border: 1px solid green;
}
.imgs {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="viewport" id="viewport">
<div class="box1">
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
<img src="./place.jpg" data-src="http://p8.qhimg.com/bdr/__85/t01e5f605262fb61fb4.jpg" alt="图片" class="imgs" />
</div>
</div>
<script>
let viewport = document.getElementById("viewport"); // 可视区域
let imgList = document.querySelectorAll(".imgs"); // 被观察元素
/* 开启观察者 */
// var IO = new IntersectionObserver(回调,配置项)
var IO = new IntersectionObserver(fn, {})
function fn (entry) {
console.log(entry, 'fn');
entry.forEach(item => {
if (item.isIntersecting) {
/* 表示进入可是区域 */
console.log(item.target.getAttribute('data-src'));
// item.target.src = item.target.getAttribute('data-src')
item.target.src = item.target.dataset.src
IO.unobserve(item.target)
} else {
/* 离开 */
}
})
}
// console.dir(IO.observe());
/* 观察img */
imgList.forEach(item => {
// console.log(item);
IO.observe(item)
})
</script>
</body>
</html>
思路三:
@vueuse/core 中的useIntersectionObserver方法
<script setup>
import {onMounted} from "vue";
import { useIntersectionObserver } from '@vueuse/core'
let itemRefs = []
const setItemRef = el => {
if (el) {
itemRefs.push(el)
}
}
//挂载后
onMounted(()=>{
//为各个div添加监控事件
console.log("onMounted div的数量:"+itemRefs.length);
for (let i=0;i<itemRefs.length;i++) {
console.log(itemRefs[i]);
useIntersectionObserver(itemRefs[i], ([{ isIntersecting }]) => {
// 如果target对应的DOM进入可视区,那么该回调函数就触发
console.log(isIntersecting);
if (isIntersecting) {
// 被监听的DOM进入了可视区:此时调用接口获取数据;停止继续监听
stop()
if (itemRefs[i].dataset.bg === '0') {
console.log(`第"+${i+1}+"个div已显示`);
//修改背景色
itemRefs[i].dataset.bg = 1;
itemRefs[i].style.background=getColor(i);
}
}
})
}
})
//返回颜色,使各个div区分开
const getColor = (idx) => {
if (idx == 0){
return "#ffff00";
} else if (idx == 1) {
return "#ff00ff";
} else if (idx == 2) {
return "#00ffff";
} else if (idx == 3) {
return "#0000ff";
} else if (idx == 4) {
return "#00ff00";
} else {
return "#ff0000";
}
}
</script>
<template>
<div>
<div>
<div data-bg="0" v-for="item in 5" :key="item" :ref="setItemRef" style="height: 500px;">
第{{item}}个盒子
</div>
</div>
</div>
</template>
思路四(小程序):
借用微信的内置 API 调用 IntersectionObserver 对象实例判断相交区域进行渲染
// pages/text/text.js
Page({
data: {
lazyList: [{
imgUrl: "https://img0.baidu.com/it/u=2566646385,2213824192&fm=253&fmt=auto&app=138&f=JPEG?w=893&h=500"
},
{
imgUrl: "https://img2.baidu.com/it/u=791640261,44080610&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
},
{
imgUrl: "https://img0.baidu.com/it/u=1732772480,1050889914&fm=253&fmt=auto&app=138&f=JPEG?w=778&h=500"
},
{
imgUrl: "https://img1.baidu.com/it/u=4001530358,139416054&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
},
{
imgUrl: "https://img1.baidu.com/it/u=3006525416,739516061&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
},
{
imgUrl: "https://img1.baidu.com/it/u=961451472,675417960&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
},
{
imgUrl: "https://img0.baidu.com/it/u=4085930884,4214873769&fm=253&fmt=auto&app=120&f=JPEG?w=667&h=500"
},
], //模拟数据
},
onLoad: function () {
// 传入参数
lazyImg(this, this.data.lazyList, 'lazyList', '../../assets/loading.gif')
}
})
const lazyImg = (that, data, name, loadingImage) => {
for (let i = 0, len = data.length; i < len; i++) {
wx.createIntersectionObserver().relativeToViewport({
bottom: 20
}).observe('.item-' + i, (ret) => {
console.log( (ret));
ret.intersectionRatio > 0 ? data[i].show = true : '';
that.setData({
[name]: data,
loading: loadingImage
})
})
}
}
<!--pages/text/text.wxml-->
<view class='item-{{index}}' wx:for="{{lazyList}}" wx:key="*this.imgUrl">
<!-- imgBox:图片类名 loadingImgBox:懒加载图片类名 -->
<image src='{{item.show? item.imgUrl : loading}}' class='{{item.show? "imgBox" : "loadingImgBox"}}'></image>
</view>
/* pages/text/text.wxss */
image {
width: 100%;
}
/* 懒加载图片样式 */
.loadingImgBox {
transition: opacity 0.4s linear 0.4s;
}