JavaScript判断各种资源是否加载完成的方法汇总,资源预加载问题

简介: JavaScript判断各种资源是否加载完成的方法汇总,资源预加载问题

将网站放在服务器后,因为服务器带宽问题,才发现很多资源比如图片、音频在网站打开后1分钟还没有加载,导致无法播放。所以说我决定使用js在最开头加一个判断资源是否加载完成的函数并运行,只有资源全加载完成了才能进入主页面。

在网上查了很多都是说用onload,但是这只能判断文档dom树是否解析完成,但是音频、图片等等资源加载完成没是无法判断的。

下面我将来分享我的方案。

1,判断音频/视频是否加载完成

音频,视频元素分别是<audio><video>,这两个元素都有readyState属性表示其是否加载完成,我们可以获取其属性值,其属性值对应意义如下:

意义
0 HAVE_NOTHING - 没有关于音频/视频是否就绪的信息
1 HAVE_METADATA - 关于音频/视频就绪的元数据
2 HAVE_CURRENT_DATA - 关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒
3 HAVE_FUTURE_DATA - 当前及至少下一帧的数据是可用的
4 HAVE_ENOUGH_DATA - 可用数据足以开始播放

那么,判断该属性值为4时,既可以知道加载完成了。

与此同时,音频和视频元素可以设定其preload属性设置其是否预加载,属性值如下:

意义
auto 当页面加载后载入整个音频
metadata 当页面加载后只载入元数据
none 当页面加载后不载入音频

默认这个值是metadata,只加载元数据。因此如果想要音频即时使用建议修改其属性为auto,然后再来查看其readyState属性来判断加载完成没,但这样网页打开可能会慢一点。

例如设定音频为自动加载:

<audiosrc="./testAudio.wav"preload="auto"></audio>

在我的一台很慢的服务器上面通过下列js每秒读取100次一个audio标签是否加载完成:

setInterval(() => {
  console.log(document.querySelector('.succeedAduio-2').readyState);
}, 10);

结果如下:

网络异常,图片无法展示
|

可见一开始没加载好就是0,最后才是4。

根据这个我们就可以知道音频组件是否加载完成,加载完成了才能播放。

视频元素也是一样的。

2,图片img元素

img元素不像音视频元素,它没有readyState这个属性,不过可以通过其complete属性来获取。当图片加载完成时,该属性值为true,否则为false

例如我这里有个img元素:

<imgsrc="https://file.moetu.org/images/2021/03/03/gz-13c176dbd1ced48543.png"/>

还是向上面一样,我用js每秒读取100次该属性:

let img = document.querySelector('img'); //获取img元素
setInterval(() => {
  console.log(img.complete);
}, 10);

结果如下:

网络异常,图片无法展示
|

可见对于img元素,通过其complete属性即可知道是否加载完成。

3,div元素的背景图片

div没有上述两个属性,但是对于有背景图片的div元素来说,又应该怎样才能知道其是否加载完成呢?

我们可以通过js获取div的style.backgroundImage的值来获取div的背景图片的地址,再以该地址为参数在js创建一个Image对象,Image对象也有complete属性,根据新建对象来判断是否加载完成。

在此先写一个函数获取div的背景图片地址:

/**
 * 获取div元素的背景图片地址
 * @param {*} divElement div元素
 */
function getDivImage(divElement) {
  let imgurl = window.getComputedStyle(divElement, null).getPropertyValue('background-image');
  return imgurl.substring(5, imgurl.lastIndexOf('\"'));
}

需要说明的是,window.getComputedStyle方法可以获取元素所有样式,具体用法可以去MDN上面查看。

例如我有一个div元素:

<divclass="divImg"></div>

它已经通过css设定了背景图片:

.divImg {
position: relative;
width: 200px;
height: 150px;
background: url("https://file.moetu.org/images/2021/03/03/ys-4b588a903494b1e90.png") no-repeatcenter/cover;
}

然后我在js中获取这个元素,并通过上述自定义函数获取其背景图片地址,创建Image对象,并每秒读取100次是否加载完成:

letdivImg=document.querySelector('.divImg'); //获取div元素letgetImg=newImage(); //新建Image对象getImg.src=getDivImage(divImg); //给Image元素指定地址setInterval(() => {
console.log(getImg.complete);
}, 10);

结果如下:

网络异常,图片无法展示
|

上述测试图都很大,所以可见这加载了大几十秒甚至1分钟才好。

4,资源预加载问题

要想实现资源预加载其实很简单,视频音频元素上面有提到,改其preload属性为auto即可。而图片预加载只需要在js里面创建一个Image对象,并指定其src即会预加载图片。例如我要预加载我所需的所有图片:

//将所需的图片地址存入一个数组constimgurls= ['https://file.moetu.org/images/2021/03/04/gz-1844d1db4a9a2d0dc3.png',
'https://file.moetu.org/images/2021/03/04/ys-5627f9c93bc08ad29.png',
'https://file.moetu.org/images/2021/03/03/ys-4b588a903494b1e90.png',
'https://file.moetu.org/images/2021/03/03/gz-13c176dbd1ced48543.png',
'https://file.moetu.org/images/2021/02/10/illust_85719128_20201120_19253792efd4d4d825d6e1.jpg'];
//遍历数组中的图片地址并创建Image对象for (leti=0; i<imgurls.length; i++) {
letimg=newImage();
img.src=imgurls[i];
}

上述代码中,我们只是用js循环遍历图片地址依次创建Image对象。其实在创建了Image对象并设定了其src属性后,图片就开始加载了!加载好后HTML中调用就无需再次加载,直接使用。

在一个没有写任何元素的HTML中调用这个js脚本执行上诉语句,可以发现虽然页面不显示任何东西,但是已经开始加载图片资源了:

网络异常,图片无法展示
|

预加载后资源可以即时使用,但是也会相应地使网站速度打开变慢,所以一般不要预加载太多资源。

相关文章
|
24天前
|
前端开发 JavaScript
前端 js 经典:数组常用方法总结
前端 js 经典:数组常用方法总结
26 0
|
28天前
|
JavaScript 前端开发 Go
动态加载与异步加载 JavaScript 详解:加载远程js,加载成功后执行回调函数
动态加载与异步加载 JavaScript 详解:加载远程js,加载成功后执行回调函数
127 1
|
2天前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
10 0
|
7天前
|
JavaScript 前端开发
JavaScript删除数组中指定元素3种方法例子
JavaScript删除数组中指定元素3种方法例子
|
8天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的学习视频资源库的系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的学习视频资源库的系统附带文章和源代码部署视频讲解等
18 0
|
9天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的高校实验室资源综合管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的高校实验室资源综合管理系统附带文章和源代码部署视频讲解等
18 5
|
14天前
|
JavaScript 前端开发
js中改变this指向、动态指定函数 this 值的方法
js中改变this指向、动态指定函数 this 值的方法
|
14天前
|
JavaScript 前端开发 开发者
JavaScript 中程序异常处理的方法,提升代码运行的健壮性
JavaScript 中程序异常处理的方法,提升代码运行的健壮性
|
14天前
|
JavaScript
分享经典面试题:JS数组去重的多种方法
分享经典面试题:JS数组去重的多种方法
|
14天前
|
JavaScript
JS判断变量是不是数组?方法大全!
JS判断变量是不是数组?方法大全!