如何同步加载图像?

Lou*_*pax 13 javascript html5

我想创建一个具有图像属性的对象,但我希望contstructor只在加载图像后才能完成运行.或者用代码来描述:

GraphicObject = Class.extend({

    //This is the constructor
    init: function(){
          this.graphic = new Image();
          this.graphic.src = 'path/to/file.png';

          while(true)
          {
              this.graphic.onload = function(){break;};
              //I know this won't work since the 'break' is on a different context
              //but you got what I try to do.
          }
     }


})
Run Code Online (Sandbox Code Playgroud)

对于那些不熟悉我在脚本中使用的Class符号的人来说,它基于

有任何想法吗?

K..*_*K.. 20

这是可能的,但只有在古代艺术Base64编码数据URL.

GIF图像转换为Base64.

rune.b64

R0lGODlhIwAjAIAAAP///wAAACwAAAAAIwAjAAACf4SPqcsb3R40ocpJK7YaA35FnPdZGxg647kyqId2SQzHqdlCdgdmqcvbHXKi4AthYiGPvp9KVuoNocWLMOpUtHaS5CS54mZntiWNRWymn14tU7c2t6ukOJlKR5OiNTzQ7wb41LdnJ1coeNg3pojGqFZniPU4lTi0d4mpucmpUAAAOw==
Run Code Online (Sandbox Code Playgroud)

通过阻止AJAX加载转换后的图像的JavaScript形成相同的服务器.

loader.js

var request = new XMLHttpRequest();
var image = document.createElement('img');

request.open('GET', 'rune.b64', false);
request.send(null);

if (request.status === 200) {
  image.src= 'data:image/gif;base64,' + request.responseText.trim();

  document.getElementsByTagName("body")[0].appendChild(image); 
}
Run Code Online (Sandbox Code Playgroud)

问题

  • 一些较旧的浏览器不喜欢(大)数据URL
  • Base64编码使图像大约增加37%
  • 整个UI被阻止,直到加载图像

这是一种非常邪恶的方式

  • 对于记录,这仍然异步加载实际图像src. (9认同)
  • +1,因为,嘿,它**回答问题; 并且你警告它是邪恶的(它是). (6认同)

Mat*_*all 14

将依赖代码放在回调中.没有其他非邪恶的方式.

GraphicObject = Class.extend({

    //This is the constructor
    init: function(){
          this.graphic = new Image();
          this.graphic.onload = function ()
          {
              // the rest of the ctor code here
          };
          this.graphic.src = 'path/to/file.png';
     }
});
Run Code Online (Sandbox Code Playgroud)

  • "非邪恶"是一种夸大其词.对于某些人来说,在数千种不同的回调中包装函数可能不是最好的解决方案. (7认同)

小智 12

有一种在 Javascript 中同步加载图像的非邪恶方法。

loadImage = async img => {
    return new Promise((resolve, reject) => {
        img.onload = async () => {
            console.log("Image Loaded");
            resolve(true);
        };
    });
};
Run Code Online (Sandbox Code Playgroud)

await随处调用它。像这样

for(let i=0;i<photos.length;i++){
    await loadImage(photos[i]);
}
Run Code Online (Sandbox Code Playgroud)

它将一张一张地加载所有图像。

注意:调用函数必须要async使用await

  • 使用“async”和“await”的要求意味着,根据定义,这不是同步的。 (5认同)

小智 5

var timeOut = 5*1000; //ms - waiting for max 5s to laoad
var start = new Date().getTime();
while(1)
  if(img.complete || img.naturalWidth || new Date().getTime()-start>timeOut)
    break;
Run Code Online (Sandbox Code Playgroud)

基于这个答案。