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

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

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

相关文章
|
3月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
3月前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
4月前
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
3月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
304 62
|
1月前
|
JavaScript 前端开发 开发者
JavaScript字符串的常用方法
在JavaScript中,字符串处理是一个非常常见的任务。JavaScript提供了丰富的字符串操作方法,使开发者能够高效地处理和操作字符串。本文将详细介绍JavaScript字符串的常用方法,并提供示例代码以便更好地理解和应用这些方法。
56 13
|
3月前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
3月前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
3月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
87 5
|
3月前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
45 1
|
3月前
|
缓存 前端开发 JavaScript
JavaScript加载优化
JavaScript加载优化

热门文章

最新文章