这两天遇到一个新需求:一个一镜到底的h5动画。因为功能的特殊性,就要求我们提前监听页面的静态图片是否全部加载完毕。即处理预加载。

总结下来,下次这种需求需要提前注意以下几点:

一、图片而不是背景图

本来,我所用到的图都是用背景图制作的(因为非接口返回的图片都要求用背景图)。

但是监听静态图片时,后来发现所用的方法监听不到背景图,所以改成了图片。

这是一个坑。

二、获取新加载的图片:Img.load()

1、要监听图片我们要先获取到页面中的所有图片:
jq的方法:find()

var MyImg = $(body).find('img');

很简单的解决了这个问题。

MyImg得到的是目标元素中的所有图片的集合。

2、然后我们要遍历所有的图片,好判断是否加载完毕:

依然是jq的方法:each()

MyImg.each(function(){
//在这里实现 分别对每一个图片的图片加载结果 的监听。
})

3、然后说如何监听图片加载:

万年青jq方法:load()

Img.load(function(){
// 回调里,执行加载完毕一个的记录处理
})

还好这次用的jq写的代码,省了不少事。

为了记录图片加载完毕的个数,我在全局设置一个变量:

var sum = 0;

并准备一个方法让sum累加

function sumAdd(){
sum++;
}

然后load方法的回调里,调用sumAdd

MyImg.load(()=>{
// 用于新加载的图片
sumAdd(1);
});

最后页面加载完成后成功得到 sum=7;(本次案例页面7张图)

三、获取缓存的图片:Img.complete

now

图片加载是能控制了,但是为什么我一刷新他又监听不到了?

哦!原来页面加载完毕后刷新,再展示的图片都是缓存的图,而load又监听不到缓存的图。

要了我的老命了。

于是我又找,什么方法能监听缓存的图啊?
目标锁定了js里的img.complete。注意划重点是js的属性
所以这里使用上要注意,因为我获取的dom对象是jq的,要转成js的再调complete属性,于是代码直接是:

if(MyImg[0].complete){
// 用于缓存图片
sumAdd();
}

有了之前准备的sumAdd函数做接应,缓存图片的个数也能计算出来了。

至此,一个非常简易又简陋的监听就完成了。

题外话

之前不是这么做的,而是load方法里累加load的个数,complete里累加缓存的个数。

在电脑上测试,两者河井互不犯,相安无事。

但是到手机上发现,会有6张缓存图1张加载图,导致下边要说的加载进度计算错误,先是变成70%,又变回20%。

后来才改成这两种情况都累加到一处了。

四、预加载进度计算并展示

好了,现在需求升级。

为了友好的用户体验,你在后台加载图片的时候,用户不能只看到一个加载中,等半天不知道到底有没有反应。

所以我们要给用户一个及时的反馈,就要获取图片加载的进度。

思路就是 :

加载进度 = 已加载图片资源个数/总的图片资源个数*100+'%';

有了公式,又有之前我们准备的sum(当前加载个数),这个加载进度轻而易举就能得到了:

let progress = Math.ceil(sum/7*100);

7是当前页面中图片的总个数。而Math.ceil向上取整是为了在除不尽的时候不会出现小数点或99.9999%的情况。
当然为了控制万一超过100的情况,只需要保险设置一下:

progress>=100?100:progress

如果加载进度想做成进度条效果,只需要把得到的progress值赋给进度条的宽度即可。
至于进度条怎么做,看我这篇博文。css案例 - 评分效果的星星✨外衣

五、数字动画效果:animate()

后来我又想,进度条旁边加数字展示岂不是更好?

而作为一个有些许追求的程序员,我又不想直接做成数字是多少就生硬切换成多少的效果。

我想做逐渐变化的数字动画效果

这就要另一个方法上场了。

对,没错,还是jq的方法 - animate()方法:

利用其step属性达到动画逐帧改变的效果,也就是文字从1累加渐变成100,而不是生硬的跳转为100。

这个方法的用法是这样的:

$('#loadingTxts').animate({count: progress},{
duration: 350,
step: function() {
if(isNaN(this.count)){
this.count = 0;
return;
}
let boxText = Math.ceil(Number(this.count));
if(boxText >= 100){
boxText = 100;
//接下来执行预加载完毕,页面开始展示
...
}
$('#loadingTxts').text(boxText+'%');// 文字展示
$('.progress').css('width',boxText+'%'); // 进度条宽度设置
}
});

一个坑接一个坑,最后我们被折磨得没了生气的力气。

大致参考代码:

$(function () {
let nameLink = 'https://www.test.com/test/dist/images/',
nameArr = ['1', '2', '3', '4', '5', '6', '7'],
myImgs = $('.baby-box').find('img'),
downAndCache = 0; function progressAni(i){
downAndCache += i;
let progreVal = Math.ceil(downAndCache/nameArr.length*100);
// 文字-单值变化动画
$('#txtsBox').animate({
count: progreVal
},{
duration: 350,
step: function() {
if(isNaN(this.count)){
this.count = 0;
return;
}
let numberTxt = Math.ceil(Number(this.count));
if(numberTxt >= 100){
numberTxt = 100;
$('.loading').fadeOut();
}
$('#txtsBox').text(numberTxt+'%');
$('#progressBox').css('width',numberTxt+'%');
}
});
}
myImgs.each(function(a){
let Img = $(this);
if(Img[0].complete){
// 用于缓存图片
progressAni(1);
}
Img.load(()=>{
// 用于新加载的图片
progressAni(1);
});
Img.error(function() {
// 图片加载失败,可以选择替换图片
console.log(Img.attr('src'));
Img.attr('src',nameLink + nameArr[a] + '.jpg');
});
});
});

  

2018-09-13 17:32:28

相同思路的 一段其他的处理方法: 2018-10-26  14:00:21

 //加载图片
var loadImgIndex = 0,
path = 'images/';
exports.loadImg = function(arr,callback){
var len = arr.length,
callback = callback || function(){};
if(!len){
return;
}
(function loading(){
var img = new Image();
img.onload = function(){
if(loadImgIndex == len-1){
callback();
}else{
loadImgIndex++;
console.log('图片已经加载:' + Math.floor(loadImgIndex/len*100) + '%');
loading();
}
}
img.src = path + arr[loadImgIndex];
img.onerror = function(){
console.log('加载失败');
setTimeout(callback,1000);
}
})(); ---------------------
//作者:kongjunchao159
//来源:CSDN
//原文:https://blog.csdn.net/kongjunchao159/article/details/49587573
//版权声明:本文为博主原创文章,转载请附上博文链接!

还有这个文章,写的讲解也很好。通俗易懂:

https://blog.csdn.net/ssisse/article/details/51655644?utm_source=blogxgwz0

js - 预加载+监听图片资源加载制作进度条的更多相关文章

  1. jQuery学习(监听DOM加载)

    jQuery的extend方法 function njQuery() { } /* njQuery.extend = function (obj) { // 此时此刻的this就是njQuery这个类 ...

  2. C# NanUI WinFormium监听页面加载开始\结束

    个人博客 地址:https://www.wenhaofan.com/article/20190501213608 因为NanUI文档中仅介绍了Formium窗口的监听,但是没有WinFormium相关 ...

  3. gulp压缩html,css,js文件流程、监听任务、使用gulp创建服务器、同时运行多个任务、反向代理

    一.初始化 首先先做一个项目初始化,用来记录你项目中用到的工具 再你项目文件下打开一个控制台,输入命令 yarn init -y 进行初始化 输入命令yarn add gulp -g  --- 全局安 ...

  4. 移动端用js与jquery实时监听输入框值的改动

    背景: 在一次移动端H5开发中,需要监听输入框值的实时变动. onchange事件肯定抛弃,因为只能失去焦点才触发. 而keyPress在Android可以触发,iOS不可以. 又不想用Android ...

  5. js与jquery实时监听输入框值变化方法

    本文实例讲述了js与jquery实时监听输入框值的oninput与onpropertychange方法.分享给大家供大家参考.具体如下: 最近做过一个项目,需求是下拉框里自动匹配关键字,具体细节是实时 ...

  6. js与jquery实时监听输入框值的oninput与onpropertychange方法

    文实例讲述了js与jquery实时监听输入框值的oninput与onpropertychange方法.分享给大家供大家参考.具体如下: 最近做过一个项目,需求是下拉框里自动匹配关键字,具体细节是实时监 ...

  7. iOS-WKWebview 带有进度条加载的ViewController【KVO监听Webview加载进度】

    前言 为什么要说 WKWebview,在之前做电子书笔记时已经提过 WKWebview 在iOS8之后已完全替代 Webview,原因就不多说了,主要还是内存过大: 封装 封装一个基于 UIViewC ...

  8. 监听spring加载完成后事件

    有这个想法是在很早以前了,那时的我没有接触什么缓存技术,只知道hibernate有个二级缓存.没有用过memcache,也没有使用过redis. 只懂得将数据放到数组里或者集合里,一直不去销毁它(只有 ...

  9. 赵雅智_service电话监听2加接通电话录音

    步骤: 创建CallStateService继承Service 取得电话服务 监听电话动作 电话监听的对象 没有电话时 停止刻录 重设 刻录完毕一定要释放资源 电话响铃时 从麦克风採集声音 内容输出格 ...

随机推荐

  1. (原)从mp4,flv文件中解析出h264和aac,送解码器解码失败

    转载请注明出处:http://www.cnblogs.com/lihaiping/p/5285166.html 今天在做本地文件解码测试,发现从mp4,flv文件中读出来的帧数据,h264和aac帧直 ...

  2. MVC4小细节

    一: @model 指令 或者也叫  @model关键字   注释:@model指令以提供一个更干净简洁的方式来指明你想要在视图文件中引用强类型模型类 作用:让视图文件(cshtml)更易读易写;VS ...

  3. 查看CentOS系统运行了多久使用uptime命令

    对于一些人来说系统运行了多久是无关紧要的,但是对于服务器管理员来说,这是相当重要的信息. 服务器在运行重要应用的时候,必须尽量保证长时间的稳定运行,有时候甚至要求零宕机. 那么我们怎么才能知道服务器运 ...

  4. linux 内存分页

    内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在其中保存数据.我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念. 内存 简单地说,内存就是一个数据货架.内存 ...

  5. 基于Java对图片进行二值化处理

    一直以来对Java的图形处理能力表无力,但好像又不是那么一回事,之前用PHP做过一些应用,涉及到验证码的识别,其中有个图片二值化的步骤,今天换成Java来实现下 在java的扩展包javax.imag ...

  6. Maven 与 IntelliJ IDEA 的完美结合

    你是否正在学习Maven?是否因为Maven难用而又不得不用而苦恼?是否对Eclipse于Maven的冲突而困惑? 那么我告诉你一个更直接更简单的解决方案: IntelliJ IDEA! 1. 什么是 ...

  7. jQuery时间格式转换

    http://www.cnblogs.com/ShaYeBlog/p/4129301.html

  8. Linux定时运行程序脚本

    项目开发中经常需要用将某个脚本定时运行从而避免其运行并不会影响到其他程序.虽说可以在脚本中利用sleep命令来做这一点,Linux自带了crontab命令可以很好的执行这一操作. 比如我们有名为som ...

  9. mysql查询两个日期之间相差多少天?

    需求描述: 在mysql中,查看两个日期之间相差多少天 操作过程: 1.通过datediff函数,查看两个日期之间相差多少天 mysql> select datediff('2018-06-26 ...

  10. HTML5标签canvas图像处理

    摘要: canvas可以读取图片后,使用drawImage方法在画布内进行重绘.本文介绍canvas的图像处理 drawImage drawImage() 方法在画布上绘制图像.画布或视频.drawI ...