How do I make an image load synchronously?

后端 未结 5 1946
暖寄归人
暖寄归人 2020-12-06 10:21

I want to create an object that has an image property, but I want the contstructor to finish running only once the image is loaded. Or to describe this with code:

         


        
相关标签:
5条回答
  • 2020-12-06 10:56
    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;
    

    Based on this answer.

    0 讨论(0)
  • 2020-12-06 11:04

    I wrapped it into function, and it worked!

    for (var i = 0, i < asset.length; i++) {
    
        var img = new Image();
        img.src = "file:///" + folder + "/" + asset[i].name;
    
        getWdrp(img);
    
        function getWdrp (img) {
            img.onload = function(){
                // work with the image file
            }
        }
    }
    

    This is an example that worked for me, because before, when I was processing the image without wrapping in the function, it would work async, now it is async.

    0 讨论(0)
  • 2020-12-06 11:12

    There is a non-evil way to load images in Javascript synchronously.

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

    Call it with await anywhere. like this

    for(let i=0;i<photos.length;i++){
        await loadImage(photos[i]);
    }
    

    It will load all images one by one.

    Note: Calling function must be async to use await

    0 讨论(0)
  • 2020-12-06 11:18

    It is possible, but only with the ancient art of Base64 and Data-URL.

    GIF image converted to Base64.

    rune.b64

    R0lGODlhIwAjAIAAAP///wAAACwAAAAAIwAjAAACf4SPqcsb3R40ocpJK7YaA35FnPdZGxg647kyqId2SQzHqdlCdgdmqcvbHXKi4AthYiGPvp9KVuoNocWLMOpUtHaS5CS54mZntiWNRWymn14tU7c2t6ukOJlKR5OiNTzQ7wb41LdnJ1coeNg3pojGqFZniPU4lTi0d4mpucmpUAAAOw==
    

    JavaScript which loads the converted image form the same server via blocking AJAX.

    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); 
    }
    

    Problems

    • Some older browsers don't like (big) Data-URLs
    • Base64 encoding makes images about 37% bigger
    • The whole UI is blocked till the image is loaded

    This is a very-evil way

    0 讨论(0)
  • 2020-12-06 11:18

    Put the dependent code in the callback. There is no other non-evil way.

    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';
         }
    });
    
    0 讨论(0)
提交回复
热议问题