+2

Handing Broken Image with “onerror”

Trong quá trình hiển thị dữ liệu lên web, vì những lý do khác nhau mà dữ liệu có thể sẽ bị lỗi hoặc được tìm thấy. Trong đó có hình ảnh, mình nhận thấy rằng việc xử lý các ảnh bị lỗi không thể hiển thị hoặc đơn giản là url không tồn tại, những vấn đề đó sẽ đi tới kết quả thường thấy như là sẽ hiển thị thường sẽ dấu “?”, hoặc không hiển thị gì tại vị trí ảnh bị lỗi (phụ thuộc vào trình duyệt) hoặc sẽ giống như hình ảnh này với cái icon rất không vui.

<!DOCTYPE html>
<html>
<body>
<img src="image.gif">
<p>Đường dẫn ảnh trong thẻ <img> không tồn tại hoặc bị lỗi</p>
</body>
</html>

Với những kiểu hiển thị báo lỗi như vậy sẽ gây cho người dùng cảm giác không thoải mái, có thể website của chúng ta sẽ có những đánh giá không tốt, và có thể rời bỏ website của chúng ta. Kể cả là các tester cũng sẽ rất confused khi họ không thể biết được lỗi từ đâu. Gần đây khi được tham gia vào 1 dự án mà nhu cầu hiển thị hình ảnh là trọng tâm, khách hàng có yêu cầu về việc hiển thị 1 hình ảnh mặc định nếu hình ảnh của họ bị lỗi. Sau một hồi research mình bắt được một đoạn code như sau :

<img src="some-broken-image-link.jpg" onerror="LoadDefaultImage(); alt="caption" />

Well, mình thề là mình chưa bao giờ nhìn thấy thứ gì như vậy trước đây, “onerror” là gì???? Mình đã ngay lập tức ghé qua w3school và tìm được thông tin như sau:“by default, have onerror javascript handlers baked in that get invoked if the image returns a non-200 status code.”

Có nghĩa là khi hình ảnh bị lỗi, event onerror sẽ được khởi động, và call function LoadDefaultImage(), trong hàm này, ta có thể hình dung là sẽ gán hình ảnh mặc định khi không tìm thấy ảnh vào thẻ <img> đang lỗi đó.

Okey, khi làm việc trong ngành công nghệ, mỗi ngày làm việc giống như là bạn đang đi học, vì mỗi ngày bạn sẽ học được thêm một điều gì đó, và điều đó mình thấy như là điều đương nhiên, so, mình thực hiện thao tác “google search” với 2 cặp từ khóa như sau: “img src”, và “img onerror”, kết quả :

  1. “img src” google trả về 224,000,000 kết quả
  2. “img onerror “ google trả về 437,000 kết quả.

Vậy là với tỉ lệ 0.195%, mọi người biết về <img> tag và xử lý onerror. Nên mình nghĩ, bài post này sẽ hữu ích cho mọi người.

Thứ nhất, bạn có thể sử dụng thuộc tính onerror của thẻ img để thay đổi img.src và thay đổi icon missing khó chịu đó cho một hình ảnh mặc định đẹp hơn mà không phá vỡ bố cục của bạn.

Thứ hai, bạn có thể đi một bước xa hơn với một sự kiện phân tích để cho bạn biết bạn đã có hình ảnh bị hỏng trong các trang của bạn, do đó bạn có thể fix chúng.

Thứ ba, với một chút javascript, bạn có thể sử dụng HTML5 data attributes để ”safely load" hình ảnh mà có thể hoặc không thể tồn tại, đảm bảo bạn ta chuyển đổi hình ảnh bị lỗi cho một hình ảnh mặc định tốt hơn mà không ai nhận thấy điều đó.

<!DOCTYPE html>
<html>
<head>
	<title>Image errors</title>
</head>
<style>
	.some-style {
		border: 10px solid black; 
		width: 100px; 
		height: 100px;
	}
	.safelyLoadImage {
		display: none;
	}
</style>
<body>
<img src="" data-imgsrc="something.jpg" class="some-style safelyLoadImage" />
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
	$(function(){
		var notFoundImage = "http://upload.wikimedia.org/wikipedia/en/thumb/d/da/Ziltoidtheomniscientcover.jpg/220px-Ziltoidtheomniscientcover.jpg";
		var realImageSrc = $(".safelyLoadImage").data("imgsrc");	
		$(".safelyLoadImage").attr("onerror", "this.onerror=null; this.src='" + notFoundImage + "';");			
		$(".safelyLoadImage").attr("src", realImageSrc);
		$(".safelyLoadImage").removeClass("safelyLoadImage");		
	});
</script>
</body>
</html>

Tại sao chúng ta cần phải viết function riêng ra mà không sử dụng onerror ngay trong thẻ <img>, bởi vì nếu ta làm như vậy, một số trình duyệt sẽ bị rơi vào vòng lặp vô hạn, nên ta cần attr onerror trong hàm và set nó bằng “null”. Sau khi kiểm tra xong ta sẽ removeClass để để check function đi.

Mong bài viết sẽ hữu ích cho bạn.

Thank for reading!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí