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脚本执行上诉语句,可以发现虽然页面不显示任何东西,但是已经开始加载图片资源了:

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

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

相关文章
|
5月前
|
监控 负载均衡 JavaScript
有哪些有效的方法可以优化Node.js应用的性能?
有哪些有效的方法可以优化Node.js应用的性能?
311 69
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
359 0
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
385 80
|
5月前
|
Web App开发 数据采集 JavaScript
动态网页爬取:Python如何获取JS加载的数据?
动态网页爬取:Python如何获取JS加载的数据?
967 58
|
11月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
242 1
|
8月前
|
前端开发 JavaScript
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
329 58
|
6月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
7月前
|
JavaScript 前端开发 Java
深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
Array.find() 是 JavaScript 数组方法中一个非常实用和强大的工具。它不仅提供了简洁的查找操作,还具有性能上的独特优势:返回的引用能够直接影响原数组的数据内容,使得数据更新更加高效。通过各种场景的展示,我们可以看到 Array.find() 在更新、条件查找和嵌套结构查找等场景中的广泛应用。 在实际开发中,掌握 Array.find() 的特性和使用技巧,可以让代码更加简洁高效,特别是在需要直接修改原数据内容的情形。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
11月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
673 62
|
7月前
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章