【问题标题】:onerror event not being detected during image preloading?图像预加载期间未检测到 onerror 事件?
【发布时间】:2014-06-10 02:10:27
【问题描述】:

我正在尝试预加载许多(数千张)图像,并认为我做得对。我有一个数组中的所有 URL(有些是有效的,有些不是)。我遍历数组,并将onloadonerror 事件附加到img.src 函数。当图像事件返回 error 时,我不会将其添加到“好”数组中,而是在我的循环中添加 continue

但是,我注意到,虽然这应该会阻止图像进入我的“好”数组,但并非总是如此(实际上我有足够的图像,我不知道它是否会这样做)。当我实际将这些图像加载到页面中时,我会在控制台中看到损坏的图像符号和 404

我在预加载时在控制台中看到404 错误,所以我假设它确实检测到一些损坏的图像但不是全部,或者它们仍然会进入我的其他阵列?可能是图像加载速度如此之快以至于我的continue 语句不起作用(有数千个)?如果是这样,有没有办法解决这个问题?我在下面附上了我的代码,这里我尝试在.onerror 条件中使用continue,但我猜img.src 使它成为无效的循环条件。感谢您的帮助。

编辑:

src 属性是对象的一个​​属性,它也会有nameuserName 属性,所以我只想添加具有有效url 的对象。我试图缩写我的代码,但应该添加这部分(我只添加了前三行,尽管我现在意识到我应该 push 项目 onload

var name = 'test',
    username = 'testUser'
    url;
for(i = 0; i < imgURLs.length; i++) {
    url = url[i];
    var img = new Image();
    valid = true;
    img.onload = function(){
        console.log('New Media Loaded')
    };
    img.onerror = function(){
        console.log('error: bad image source');
        valid = false;
    };
    img.src = url;
    if(valid) {
       goodArray.push(img);
    }
}

【问题讨论】:

    标签: javascript jquery ajax image preload


    【解决方案1】:

    onerror 是异步的。它发生在未来的某个时间。您在 onerroronload 运行之前很久就在测试 valid 变量。如果您只想将好的图像推送到数组中,那么您应该将它们推送到 onload 处理程序中的数组中,如下所示:

    for(i = 0; i < imgURLs.length; i++) {
        var img = new Image();
        img.onload = function(){
            console.log('New Media Loaded')
            goodArray.push(this);
        };
        img.onerror = function(){
            console.log('error: bad image source');
        };
        img.src = url;
    }
    

    仅供参考。请注意,我也推送this,而不是img,因为img 变量已被for 循环的后续迭代更改,但this 将是刚刚成功加载的图像。


    如果您想要一个图像预加载器,它会在最后一张图像加载时发出通知,您可以使用代码形式this answer

    【讨论】:

    • 谢谢。我没有在我的代码中指定这是需要推送的较大对象的一个​​属性(我只是编辑了它),如果你要初始化/添加整个对象,你会把它放在我做的地方吗(在你设置之后urlonload 部分?
    • @Startec - 你知道图像是否成功加载的唯一地方是onload 处理程序。所以,如果你只想推送好的图片,那么你必须要么从那里推送它们,要么从那里调用一个函数来推送它们。这是您仅有的两个选择。
    • 关于您的仅供参考... this 或声明排序 o = new Object(); o.pic = img 是否始终引用“正确”图像(即创建时循环中的 URL)。换句话说,即使循环继续到其他图像,他们也会“记住”他们的 img 属性。 (类似var 不会?)
    • @Startec - 我必须查看您要询问的实际代码。在for 循环中覆盖的局部变量和局部变量的属性对此不起作用。如果你有其他东西要存储,你可以创建一个闭包——这里的例子:stackoverflow.com/questions/750486/…
    • @Startec - 我无法准确理解您所询问的代码。
    【解决方案2】:

    Javascript 是异步的。您的条件( if(valid) )在加载之前进行了测试。 如果要将好的图片推送到数组中,请在“onload”事件中推送。

    for(i = 0; i < imgURLs.length; i++) {
        var img = new Image();
    
        img.onload = function(){
            goodArray.push(this);
            console.log('New Media Loaded')
        };
    
        img.onerror = function(){
            console.log('error: bad image source');
        };
    
        img.src = url;
    }
    

    之后,如果你想在加载所有图像后添加一个动作,添加一个类似的计数器

    var imagesCount = imgURLs.length,
        counter     = 0;
    
    for(i = 0; i < imagesCount; i++) {
        var img     = new Image();
    
        img.onload = function(){
            goodArray.push(this);
            console.log('New Media Loaded')
    
            counter++;
    
            if(counter == imagesCount) yourAction();
        };
    
        img.onerror = function(){
    
            console.log('error: bad image source');
    
            counter++;
    
            if(counter == imagesCount) yourAction();
        };
    
        img.src = url;
    }
    
    function yourAction(){
        // your final action here ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多