2010-06-10 68 views
47

Sau khi người dùng tải lên tệp, chúng tôi phải thực hiện một số xử lý bổ sung với các hình ảnh như thay đổi kích thước và tải lên S3. Điều này có thể mất tới 10 giây. Rõ ràng chúng tôi làm điều này trong một nền tảng. Tuy nhiên, chúng tôi muốn hiển thị cho người dùng trang kết quả ngay lập tức và chỉ hiển thị các trình quay tại chỗ cho đến khi hình ảnh đến nhà vĩnh viễn của họ trên s3.Phát hiện hình ảnh 404 trong javascript

Tôi đang tìm cách phát hiện một hình ảnh nhất định không thể tải đúng (404) theo cách trình duyệt chéo. Nếu điều đó xảy ra, chúng tôi muốn sử dụng JS để hiển thị một spinner ở vị trí của nó và tải lại hình ảnh sau mỗi vài giây cho đến khi nó có thể được nạp thành công từ s3.

+1

IIRC, có sự kiện onerror cho hình ảnh ... http://www.devguru.com/technologies/javascript/10916.asp – scunliffe

+2

Xem http://stackoverflow.com/questions/92720/jquery-javascript -to-replace-broken-images –

Trả lời

8

Từ: http://lucassmith.name/2008/11/is-my-image-loaded.html

// First a couple helper functions 
function $(id) { 
    return !id || id.nodeType === 1 ? id : document.getElementById(id); 
} 
function isType(o,t) { return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;} 

// Here's the meat and potatoes 
function image(src,cfg) { var img, prop, target; 
    cfg = cfg || (isType(src,'o') ? src : {}); 

    img = $(src); 
    if (img) { 
     src = cfg.src || img.src; 
    } else { 
     img = document.createElement('img'); 
     src = src || cfg.src; 
    } 

    if (!src) { 
     return null; 
    } 

    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth'; 
    img.alt = cfg.alt || img.alt; 

    // Add the image and insert if requested (must be on DOM to load or 
    // pull from cache) 
    img.src = src; 

    target = $(cfg.target); 
    if (target) { 
     target.insertBefore(img, $(cfg.insertBefore) || null); 
    } 

    // Loaded? 
    if (img.complete) { 
     if (img[prop]) { 
      if (isType(cfg.success,'f')) { 
       cfg.success.call(img); 
      } 
     } else { 
      if (isType(cfg.failure,'f')) { 
       cfg.failure.call(img); 
      } 
     } 
    } else { 
     if (isType(cfg.success,'f')) { 
      img.onload = cfg.success; 
     } 
     if (isType(cfg.failure,'f')) { 
      img.onerror = cfg.failure; 
     } 
    } 

    return img; 
} 

Và đây làm thế nào để sử dụng nó:

image('imgId',{ 
    success : function() { alert(this.width); }, 
    failure : function() { alert('Damn your eyes!'); }, 
}); 

image('http://somedomain.com/image/typooed_url.jpg', { 
    success : function() {...}, 
    failure : function() {...}, 
    target : 'myContainerId', 
    insertBefore : 'someChildOfmyContainerId' 
}); 
+0

Điều này đặt ra một điểm tốt.Bạn (OP) cần tải các hình ảnh với các tham số chuỗi truy vấn ngẫu nhiên. – SLaks

+6

Liên kết đã chết. Câu trả lời này phải được sửa đổi để chứa nội dung hoặc bị xóa màu xanh lá cây. – mxcl

+0

KISS (aka Keep It Super Simple) –

49

Xử lý sự kiện onerror của phần tử <img>.

+9

@xal: Chỉ cần chắc chắn móc sự kiện 'error' * trước * bạn đặt thuộc tính' src' (nếu bạn đang làm điều này với 'new Image' hoặc' document.createElement ("img") 'thay vì thông qua chuỗi HTML). Nếu không, bạn đang ở trong một điều kiện đua và sự kiện có thể kích hoạt trước khi bạn bắt đầu xử lý nó (giống như sự kiện 'load'). –

+1

@ T.J: Không nhất thiết. Javascript chạy trên chuỗi giao diện người dùng, vì vậy nếu bạn xử lý sự kiện ngay lập tức sau khi đặt 'src', sẽ không có bất kỳ rủi ro nào. Tuy nhiên, bạn vẫn đúng, – SLaks

+7

Chạy Javascript trên chuỗi Javascript, mà trên * một số trình duyệt * cũng là chuỗi giao diện người dùng. Nó không nhất thiết phải là chuỗi tải xuống. Tôi đã giúp mọi người sửa lỗi gây ra bởi chính xác điều này, thiết lập 'src' trước khi thiết lập một trình xử lý' load'. Có một điều kiện chủng tộc ở đó. Nếu bạn đã có trình xử lý đã đăng ký, mã xử lý sự kiện sẽ đặt nó trên ngăn xếp thực hiện để chạy sau khi chuỗi JS có sẵn để thực hiện điều gì đó khác. Nếu không, bạn có thể bỏ lỡ sự kiện này. –

0

này đã làm việc cho tôi (tôi là trong coffeescript). Thay vào đó, bạn sẽ cần phải thay thế bằng một spinner.

checkImages = -> 
    $("img").each -> 
    $(this).error -> 
     $(this).attr("src", "../default/image.jpg") 

$(document).on('page:load', checkImages) 

Tôi đoán tương đương với javascript là một cái gì đó giống như

function checkImages() { 
    $("img").each(function() { 
    $(this).error(function() { 
     $(this).attr("src", "../default/image.jpg"); 
    }); 
    }); 
}; 

$ (document) .Trên ("page: tải", checkImages);

9

chỉ cần liên kết trình kích hoạt attr trên sự kiện lỗi.

$(myimgvar).bind('error',function(ev){ 
    //error has been thrown 
    $(this).attr('src','/path/to/no-artwork-available.jpg'); 
}).attr('src',urlvar); 
+1

Giả định rằng tất cả tải không thành công là 404. – Bangkokian

7

tùy chọn đầu tiên:

<img src="picture1.gif" onerror="this.onerror=null;this.src='missing.gif';"/> 

Thứ hai tùy chọn:

<html> 
<head> 
<script type="text/javascript"> 
    function ImgError(source){ 
     source.src = "/noimage.gif"; 
     source.onerror = ""; 
     return true; 
    } 
</script> 
</head> 
<body> 
    <img src="image_example1.jpg" onerror="ImgError(this)" /> 
</body> 
</html> 

Ví dụ trong Fidler

https://jsfiddle.net/dorathoto/8z4Ltzp8/

Các vấn đề liên quan