【问题标题】:Javascript Preload Image after window has loaded窗口加载后的Javascript预加载图像
【发布时间】:2014-02-02 02:33:30
【问题描述】:

我正在开展一个项目,该项目要求用户将图像加载到画布中,该画布根据他们所做的选择放置在灯箱中。

在用户单击按钮之前不会加载任何图像,然后在 XHR 请求中接收图像 URL。..

我在加载图像和推迟执行后面的代码时遇到问题...

我的图片加载功能是这样的..

function preloadImage(url){
    var img = new Image();
        if (!img.complete) {
            console.log('not complete');
            //return false;
        }
        if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
            console.log('no width');
            //return false;
        }
    img.onerror='Image failed to load...';
    img.src = url;
}

在代码中我在设置我的画布元素之前调用它...这个...

preloadImage(url);
setstage(url);

画布有时会及时获取图像来设置我的舞台,但有时不会,所以我有一个空白的舞台:/。有没有办法可以做到这一点并以某种方式解决此图像预加载问题?

【问题讨论】:

  • 只需使用图片的onload 事件即可。
  • 你能在 preloadimage 中调用 setstage 吗?
  • mmm.. 我想我可以重写代码来做到这一点,是的......你的意思是把 img.onload = function() { // 在这里执行 setstage(url) };在预加载函数中?

标签: javascript html image canvas


【解决方案1】:

我真的迫于压力想出一个相当可靠和稳定的解决方案,我最终阅读了大量在线文章和其他开发人员的经验,我得出了一个可靠的预加载回调。 ..

功能就是这样……

function preloadimages(arr){
    var newimages=[], loadedimages=0
    var postaction=function(){}
    var arr=(typeof arr!="object")? [arr] : arr
    function imageloadpost(){
        loadedimages++
        if (loadedimages==arr.length){
            postaction(newimages) //call postaction and pass in newimages array as parameter
        }
    }
    for (var i=0; i<arr.length; i++){
        newimages[i]=new Image()
        newimages[i].src=arr[i]
        newimages[i].onload=function(){
            imageloadpost()
        }
        newimages[i].onerror=function(){
            imageloadpost()
        }
    }
    return { //return blank object with done() method
        done:function(f){
            postaction=f || postaction //remember user defined callback functions to be called when images load
        }
    }
}

一个简单的用例是

 preloadimages(IMAGES-ARRAY).done(function(images){
      // code that executes after all images are preloaded
  });

如果有人有改进欢迎您扩展和评论,也许有人会从中受益。

【讨论】:

    【解决方案2】:

    尝试在 preloadImage 中使用回调:

     function preloadImage(url, callback) {
    
        var img = new Image();
    
        img.onerror = function() {
    
            callback('error', url, img);
        };
    
        img.onload = function() {
    
            callback(null, url, img);
        };
    
        img.src = url;
    }
    
    preloadImage(url, function(err, url, img) {
    
        if (err) {
            console.log('something wrong!!', url);
            return;
        }
    
        //get more params from img..
        setstage(url);
    });
    

    ..

    function foo() {
    
        //here are some params
        var srcx = 1, id = 2, x = 3, y = 4;
    
        preloadImage(url, function(err, url, img) {
    
            if (err) {
                console.log('something wrong!!', url);
                return;
            }
    
            //more params
            var width = 5, height = 6;
    
            setstage(srcx, id, x, y, width, height);
        });
    }
    

    【讨论】:

    • 我认为我的回调函数可以有 x 个参数(不仅仅是一个)?我使用的实际函数接收 6 个参数。 setstage(srcx, id, x, y, width, height)
    • 我不确定这些参数是什么意思,但你可以从 img 元素本身获取它们,对吧?
    • 不,不,参数被传递给在画布元素上创建舞台的设置舞台函数,它们不是来自图像,而是“用于图像”,因为它将在画布上。 .
    • 对不起,我可能不明白你的意思。但是callback只是传入preloadImage的一个函数参数,与“setstage”无关。你可以在任何地方调用 preloadImage,比如在 foo 中,并且只有当这些参数在范围内时才将任何参数传递给 setstage。
    【解决方案3】:

    有多种方法可以做到这一点。最简单的方法是等待调用setStage,直到img.onload 事件触发。如果您出于某种原因需要在与 preloadImage(url) 相同的范围内执行此操作(不确定可能是什么原因),您可以通过在 image.onloadcallback 中返回的承诺执行下一步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      相关资源
      最近更新 更多