如何知道浏览器在加载图像后何时完成处理
How to know when browser finish to process an image after loading it?
当创建一个图像对象时,可以使用"complete"属性或"onload"方法知道何时完全加载,然后,该图像已经处理(例如调整大小)使用一些时间,在大文件中可能是几秒钟。
如何知道当浏览器完成处理一个图像加载后?
编辑:在示例中可以看到"完成"消息和图像外观之间的延迟,我想避免这种情况。
使用"onload"方法的示例:
var BIGimage;
putBIGimage();
function putBIGimage(){
BIGimage=document.createElement("IMG");
BIGimage.height=200;
BIGimage.src="http://orig09.deviantart.net/5e53/f/2013/347/f/d/i_don_t_want_to_ever_leave_the_lake_district_by_martinkantauskas-d6xrdch.jpg";
BIGimage.onload=function(){waitBIGimage();};
}
function waitBIGimage(){
console.log("Complete.");
document.body.appendChild(BIGimage);
}
使用"complete"属性的例子:
var BIGimage;
putBIGimage();
function putBIGimage(){
BIGimage=document.createElement("IMG");
BIGimage.height=200;
BIGimage.src="http://orig09.deviantart.net/5e53/f/2013/347/f/d/i_don_t_want_to_ever_leave_the_lake_district_by_martinkantauskas-d6xrdch.jpg";
waitBIGimage();
}
function waitBIGimage(){
if (!BIGimage.complete){
console.log("Loading...");
setTimeout(function(){
waitBIGimage();
},16);
} else {
console.log("Complete.");
document.body.appendChild(BIGimage);
}
}
编辑:感谢@Kaiido的回应,我制作了这个解决方案来等待图像处理。
var imagesList=["https://omastewitkowski.files.wordpress.com/2013/07/howard-prairie-lake-oregon-omaste-witkowski-owfotografik-com-2-2.jpg",
"http://orig03.deviantart.net/7b8d/f/2015/289/0/f/0ffd635880709fb39c2b69f782de9663-d9d9w6l.jpg",
"http://www.livandiz.com/dpr/Crater%20Lake%20Pano%2016799x5507.JPG"];
var BIGimages=loadImages(imagesList);
onLoadImages(BIGimages,showImages);
function loadImages(listImages){
var image;
var list=[];
for (var i=0;i<listImages.length;i++){
image=document.createElement("IMG");
image.height=200;
image.src=listImages[i]+"?"+Math.random();
list.push(image);
}
return list;
}
function showImages(){
loading.style.display="none";
for (var i=0; i<BIGimages.length;i++){
document.body.appendChild(BIGimages[i]);
}
};
function onLoadImages(images,callBack,n) {
if (images==undefined) return null;
if (callBack==undefined) callBack=function(){};
else if (typeof callBack!="function") return null;
var list=[];
if (!Array.isArray(images)){
if (typeof images =="string") images=document.getElementById(images);
if (!images || images.tagName!="IMG") return null;
list.push(images);
} else list=images;
if (n==undefined || n<0 || n>=list.length) n=0;
for (var i=n; i<list.length; i++){
if (!list[i].complete){
setTimeout(function(){onLoadImages(images,callBack,i);},16);
return false;
}
var ctx = document.createElement('canvas').getContext('2d');
ctx.drawImage(list[i], 0, 0);
}
callBack();
return true;
}
<DIV id="loading">Loading some big images...</DIV>
HTMLImageElement接口有一个decode()
方法,它允许我们等待,直到图像准备好被绘制,就像你想要的。
var BIGimage;
putBIGimage();
function putBIGimage() {
BIGimage = document.createElement("IMG");
BIGimage.height = 200;
BIGimage.src = "https://upload.wikimedia.org/wikipedia/commons/c/cf/Black_hole_-_Messier_87.jpg?r=" + Math.random();
BIGimage.onload = e => console.log('load event', performance.now());
BIGimage.decode().then(waitBIGimage);
BIGimage.onerror = console.error;
}
function waitBIGimage() {
// uses the synchronous testing method to check it works fine
var start = performance.now();
// only to see if it worked fine
var ctx = document.createElement('canvas').getContext('2d');
ctx.drawImage(BIGimage, 0, 0);
ctx.drawImage(ctx.canvas, 0, 0);
var end = performance.now();
console.log(`it took ${end - start}ms to draw`)
// do your stuff
document.body.appendChild(BIGimage);
}
另一种方法是使用CanvasContext2D drawImage
方法可以同步的事实。有些浏览器可能会尝试延迟下一个画框的实际绘制,但是通过将画布绘制到自身上,我们可以强制大多数当前的UAs同步渲染我们的图像。
所以你可以在你的waitBIGimage
方法中使用它作为等待方法。
var BIGimage;
putBIGimage();
function putBIGimage() {
BIGimage = document.createElement("IMG");
BIGimage.height = 200;
BIGimage.src = "https://upload.wikimedia.org/wikipedia/commons/c/cf/Black_hole_-_Messier_87.jpg?r=" + Math.random();
BIGimage.onload = waitBIGimage;
BIGimage.onerror = console.error;
}
function waitBIGimage() {
// only for demo
// we've got to also log the time since even the console.log method will be blocked during processing
var start = performance.now();
console.log('waiting', start);
// this is all needed
var ctx = document.createElement('canvas').getContext('2d');
ctx.drawImage(BIGimage, 0, 0);
// on some system the drawing of the image may be delayed to the next painting frame
// we can try force the synchronous rendering by drawing the canvas over itself
ctx.drawImage(ctx.canvas, 0, 0);
// demo only
var end = performance.now();
console.log("Complete.", end);
console.log(`it took ${end - start}ms`)
// do your stuff
document.body.appendChild(BIGimage);
}
在我的Firefox上,处理图像大约需要1秒,而在我的Chrome上,它要快一点。
但是method的一个大问题是它是同步的,因此会在处理图像的所有时间阻塞脚本。
另一种方法是使用createImageBitmap()
方法,它应该在GPU中分配图像位图,准备绘制。
没有可靠的方法来知道-你的浏览器可以继续执行任意javascript或执行内置函数(即,调整浏览器窗口的大小),这可以直接或间接地影响图像,并导致它被重新绘制,或者看起来没有完成绘制一段时间。
你可以在一个图像的生命周期内挂接特定的事件,但是,严格地说,"finish"只在浏览器窗口关闭时发生。
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- keyup事件处理程序更改焦点不适用于快速键入
- 如何使用jquery处理php循环通过元素
- angular.js没有'无法在PhoneGap中处理视图标记
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 提示使用服务器端事件处理程序激活JavaScript
- javascript:如何在antlr生成的Lexer中进行错误处理
- 如何编写一个具有公共标头的批处理
- 在同一个服务工作者中处理service-worker.js有任何影响吗
- 如何处理node.js节点mongodb中的连接和查询队列
- 通过命令行/批处理文件打开页面时,将javascript代码注入Google Chrome
- AngularJS-由$scope创建的作用域何时执行$new()已删除.垃圾收集器或Angular负责处理它吗
- 为什么 Mocha 在报告者处理完测试失败之前退出
- jQuery处理程序,以知道何时在输入文本元素中键入了至少1个字符
- 在Node.js中,我如何判断何时解析完网页
- 在处理完整个For循环后发出嵌套的HTML5 Web SQL查询
- 使用jQuery getJSON并在处理完结果后激发一个函数..应该有效..但是没有't
- 如何处理何时使用 Javascript 单击弹出的网页上的 x 按钮
- 如果没有事件处理程序,网页如何知道我何时与元素交互
- 如何知道浏览器在加载图像后何时完成处理