JavaScript小面试~~JavaScript实现图片懒加载,多方式解决加载过多问题
图片懒加载,就是滚动页面时,图片未出现在可视局域时不加载图片,只有图片出现在可视区域才加载。
思路:通过上面一段话,实现图片懒加载需要知道:
- 绑定滚动事件
- 可视窗口高度(VH)
- 图片元素距离可视局域顶部距离(EH)
- 如何加载图片
当VH大于EH时,图片出现在可视窗口,反之。
如何加载图片呢?我们可以为img标签绑定任意非其属性名的属性,将图片路径作为其属性值,例如:
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img imgUrl="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img aabbc="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
都是可以的,这里我们使用
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
来举例子:
首先需要获取img元素的DOM对象集合
let imgs = document.querySelectorAll('img')
遍历img的DOM对象集合,获取每个img的DOM对象
imgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
// 获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src',item.getAttribute('data-src'))
}
})
通过DOM对象的getBoundingClientRect().top获取该元素距离视口顶部的高度,通过window.innerHeight获取到视口高度。
item.getAttribute('data-src'):表示获取该DOM对象上名data-src属性的属性值。
item.setAttribute(attributeName,attributeValue):表示将attributeValue值作为属性值赋值给attributeName属性。
此时我们需要绑定一个滚动事件,这个事件绑定给window,每次只要滚动条发生滚动都会触发:
let imgs = document.querySelectorAll('img')
// 为window绑定滚动事件
window.addEventListener('scroll', (e) => {
// 遍历img的DOM对象集合,获取每个img的DOM对象
mgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
//获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src',item.getAttribute('data-src'))
}
})
})
这是会有一个问题,就是每次滚动都会触发滚动事件,这会导致资源加载过多,浪费资源。
这里给出的解决方法有三个,
2,考虑兼容性:使用防抖或者节流
这里使用节流来举例(防抖可以自己去实现)
<script>
// 1获取img元素的DOM对象
let imgs = document.querySelectorAll('img')
// 为window绑定滚动事件
window.addEventListener('scroll', imgLazyLoading())
function imgLazyLoading() {
let timer
return () => {
if (timer) {
return;
}
timer = setTimeout(() => {
imgs.forEach(item => {
// 获取到每个img距离可视区域顶部的距离和可视局域的高度,并进行比较
if (item.getBoundingClientRect().top < window.innerHeight) {
// 获取元素属性为data-src的属性值,并赋值给imgDOM实例的src属性上
item.setAttribute('src', item.getAttribute('data-src'))
}
})
timer = null
}, 500)
}
}
</script>
节流或者防抖也会导致图片加载过多,但是比起不加,这种方式更加节省浏览器资源。
3,不考虑兼容性
使用IntersectionObserver构造函数(浏览器提供的构造函数,有些浏览器不支持)。这个是可以实现交叉观察,什么是交叉观察呢?就是可以知道目标元素和可视窗口是否发生交叉局域
IntersectionObserver构造函数提供了两个方法用于对目标元素进行观察和取消观察。
observe(DOM节点):观察元素
unobserve(DOM节点):取消观察
创建实例:
let observer=new IntersectionObserver(callBack)
callBack是一个回调函数,它执行两次,一次是目标元素和可视窗口发生交叉时调用,一次是不发生交叉时调用(看见时调用一次,看不见时调用一次)
callBack回调函数接收一个参数,该参数包含被观察DOM节点相关信息和观察状态的数组,其中我们需要的是每个数组项中的:
target:被观察的DOM节点实例
isIntersecting:是否被观察到,观察到的时候,我们只需要通过unobserve(DOM节点)取消观察。完成代码为:
<!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>
</head>
<style>
div {
height: 100vh;
width: 1000px;
position: relative;
top: 50%;
left: 50%;
transform: translate(50% 50%);
}
img {
padding-top: 50px;
margin-bottom: 50px;
height: 500px;
width: 500px;
background-repeat: no-repeat;
background-size: 100% 100%;
display: inline-block;
border-top: 2px solid red;
}
</style>
<body>
<div>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>11111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt="">
<img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt="">
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<img data-src="./img/7ff513a853b6d50887606dc436b1ddff.jpeg" alt="">
<img data-src="./img/8a728780b5ddd5672eb5bf8a4ce23c86.jpeg" alt="">
<img data-src="./img/ec6c60c8c5de6d7fa899807cfa8d46f1.jpeg" alt="">
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
<p>3ewrw山东省地方第三方的范德萨发水电费第三方第三方电风扇方式对方水电费</p>
<p>1111111111111111111111111111111111111111111111111111111111111111</p>
<p>22222222222222222222222222222222222222222222222222222222222222</p>
</div>
</body>
<script>
let imgs = document.querySelectorAll('img')
let observer=new IntersectionObserver(callBack)
imgs.forEach(imgItem=>{
// 观察节点,触发new IntersectionObserver(callBack)内的回调函数
observer.observe(imgItem)
})
// IntersectionObserver会向回调函数传入一个参数
function callBack(observerArray){
// observerArray:每个被观察元素对象的实例和观察状态集合
observerArray.forEach(item=>{
// item:被观察元素对象的实例和观察状态信息
// isIntersecting:是否被观察到
if(item.isIntersecting){
// item.target:被观察到实例
let imgDom=item.target
imgDom.setAttribute('src', imgDom.getAttribute('data-src'))
// 被观察到取消观察
observer.unobserve(imgDom)
}
console.log(item);
})
}
</script>
</html>
(LEARN FROM 技术蛋老师)
看都看到这了,点个赞吧,大晚上的写也不容易~~~~~算我球球你了(AQA)
JavaScript小面试~~JavaScript实现图片懒加载,多方式解决加载过多问题的更多相关文章
- 基于javascript实现图片懒加载(亲测有效)
这篇文章主要介绍了javascript实现图片懒加载的方法及思路,有时我们需要用懒加载,也就是延迟加载图片的方式,来提高网站的亲和力,需要的朋友可以参考下! 一.定义 图片延迟加载也称为懒加载,延迟加 ...
- javascript图片懒加载与预加载的分析
javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念. 懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...
- JavaScript之图片懒加载的实现
图片懒加载指的是在浏览过程中随着需要才被加载出来,例如某宝上面浏览商品时,会伴随很多的图片,如果一次全部加载出来的话,显然资源有些浪费,并且加载速度也会相对降低,那么懒加载的实现很重要.即随着浏览翻阅 ...
- js, javascript 图片懒加载 实例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript原生图片懒加载
一,原生javascript图片懒加载 1. 使用方法,例如 // 要绑定的图片地址 <img data-src={url} alt=" "> 2. 在页面中引入下列原 ...
- Javascript图片懒加载
懒加载的意义 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数. 懒加载的实现 1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟. 2.第二种是条 ...
- JavaScript——图片懒加载
前言 有一个朋友问我这个问题,刚好有时间,现在就简单的写个Demo~ github | https://github.com/wangyang0210/bky/tree/picLoadLazy 内容 ...
- 微信小程序的图片懒加载
在普通的web页面当中,我们都知道图片懒加载可以提升浏览器的加载速度.原理是图片用空或者占位图片进行显示,当屏幕移动到图片位置的时候,再把图片的地址换成它的地址.那么,在小程序当中呢,最近老大让看一下 ...
- JS图片懒加载
简介 当页面图片太多时,加载速度就会很慢.尤其是用2G/3G/4G访问页面,不仅页面慢,而且还会用掉很多流量.图片懒加载的原理就是将页面内所有需要加载的图片全部换成一张默认的图片(一般尺寸很小),只有 ...
- 前端性能优化--图片懒加载(lazyload image)
话说前头: 上次写了一篇webpack的学习心得,webpack能做到提升前端的性能,其模块打包最终生成一个或少量的文件能够减少对服务端的请求.除此之外,本次的图片懒加载(当然不仅限于图片,还可以有视 ...
随机推荐
- redis 的下载与安装
下载地址:https://github.com/MicrosoftArchive/redis/releases 选择免安装包: 解压到路径 D:\Redis-x64-3.0.504 用管理员权限打开 ...
- truffle 框架complie错误。
第一次使用trulle框架编译合约发现编译失败,原因是没有在truffle-config.js文件中加入编译器版本. module.exports = { // See <http://truf ...
- Swift Lazy计算属性的线程安全分析
一.代码示例 // // ViewController.swift // LazyTest // // Created by lilun.ios on 2021/7/30. // import UIK ...
- iOS性能优化-内存泄漏
一.现象 最近直播助手在iOS11 ReplayKit上面经常出现进程使用内存超过50MB被系统杀掉,并且这种进程被杀掉不会有任何crash log留下来,只能在Console中留下一点消息. 二.使 ...
- 音视频学习--H264解析渲染
一.H264文件获取 下载一段MP4文件,通过FFMPEG转换成MP4 ffmpeg -i Gravity.mp4 -vcodec h264 out_2.264 二.通过解析H264成帧,然后刷新 这 ...
- TensorRT环境配置(VS+opencv4.5)
1 TensorRT下载 下载与TensorRT相匹配的CUDA和cuDNN版本:https://docs.nvidia.com/deeplearning/tensorrt/archives/tens ...
- 【Socket】解决TCP粘包问题
一.介绍 TCP一种面向连接的.可靠的.基于字节流的传输层协议. 三次握手: 客户端发送服务端连接请求,等待服务端的回复. 服务端收到请求,服务端回复客户端,可以建立连接,并等待. 客户端收到回复并发 ...
- 数据结构 顺序表(C语言 与 Java实现)以及部分练习题
目录 数据结构 数组(顺序表) 特点 使用Java实现更高级的数组 C语言实现 总结 优点 缺点 例题 26. 删除有序数组中的重复项 1. 两数之和 27. 移除元素 153. 寻找旋转排序数组中的 ...
- vue3 KeepAlive
在Vue.js 3中,<keep-alive> 是一个抽象组件,用于保留其子组件状态,防止在切换组件时销毁它们.这对于在页面间切换时保留组件的状态或避免重复渲染特定组件非常有用.<k ...
- Linux扩展篇-shell编程(五)-流程控制(四)-while语句
基本语法: while [ condition ] do statement done 或 while [ condition ]; do statement done 注意事项: 实践: