Nhập hình ảnh mặc định trong trường hợp thuộc tính src của html <img> không hợp lệ?


268

Có cách nào để hiển thị hình ảnh mặc định trong <img>thẻ HTML không , trong trường hợp srcthuộc tính không hợp lệ (chỉ sử dụng HTML)? Nếu không, cách nhẹ nhàng của bạn để làm việc xung quanh nó là gì?


3
HTML không có dự phòng cho hình ảnh bị hỏng. Bạn cần sử dụng JavaScript để tìm hình ảnh bị hỏng và thay đổi thuộc tính src của chúng.
Blixt

2
@Blixt - Điều gì sẽ xảy ra nếu ứng dụng khách của bạn là MS Outlook hoặc một số trình đọc EMAIL khác và bạn không có Javascript và tùy chọn đối tượng không hoạt động ... Tôi cho rằng giải pháp duy nhất là alt / text
Xofo

Câu trả lời:


319

Bạn đã yêu cầu một giải pháp chỉ HTML ...

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

<head>
  <title>Object Test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<body>

  <p>
    <object data="http://stackoverflow.com/does-not-exist.png" type="image/png">
      <img src="https://cdn.sstatic.net/Img/unified/sprites.svg?v=e5e58ae7df45" alt="Stack Overflow logo and icons and such">
    </object>
  </p>

</body>

</html>

Vì hình ảnh đầu tiên không tồn tại, dự phòng (các họa tiết được sử dụng trên trang web này *) sẽ hiển thị. Và nếu bạn đang sử dụng một trình duyệt thực sự cũ không hỗ trợ object, nó sẽ bỏ qua thẻ đó và sử dụng imgthẻ đó. Xem trang web caniuse để tương thích. Yếu tố này được hỗ trợ rộng rãi bởi tất cả các trình duyệt từ IE6 +.

* Trừ khi URL cho hình ảnh thay đổi (một lần nữa), trong trường hợp đó bạn có thể sẽ thấy văn bản thay thế.


3
Nó hoạt động với tôi trong IE8 sau khi tôi đưa vào DTD cho HTML 4.01.
Patrick McElhaney

Điều này không hoạt động nếu hình ảnh không tồn tại đã X-Frame-Optionsđược đặt thành SAMEORIGINhoặc cài đặt dễ dàng hơn.
Attila O.

Nó hoạt động nhưng nếu liên kết trong object.data không đáng tin cậy, nó có thể tải tất cả các loại nội dung ...
Michael_Scharf

1
Phần tử 'img' không thể được lồng bên trong phần tử 'đối tượng'.
Matheus Miranda

2
@Meditus Chắc chắn nó có thể. Trong đối tượng HTML4 có thể chứa nội dung luồng (hầu hết mọi thứ, kể cả img) và trong HTML5, nó trong suốt, có nghĩa là nó có thể chứa bất kỳ HTML5 hợp lệ nào.
Patrick McElhaney

318

Công việc này tốt cho tôi. Có lẽ bạn muốn sử dụng JQuery để nối sự kiện.

 <img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';">

Cập nhật với bảo vệ lỗi jacquargs

Đã cập nhật: Giải pháp duy nhất về CSS Tôi mới thấy Vitaly Friedman giới thiệu một giải pháp CSS tuyệt vời mà tôi không biết. Ý tưởng là áp dụng contenttài sản cho hình ảnh bị hỏng. Thông thường :afterhoặc :beforekhông áp dụng cho hình ảnh, nhưng khi chúng bị hỏng, chúng được áp dụng.

<img src="nothere.jpg">
<style>
img:before {
    content: ' ';
    display: block;
    position: absolute;
    height: 50px;
    width: 50px;
    background-image: url(ishere.jpg);
</style>

Bản trình diễn: https://jsfiddle.net/uz2gmh2k/2/

Như fiddle cho thấy, bản thân hình ảnh bị hỏng không bị xóa, nhưng điều này có thể sẽ giải quyết vấn đề cho hầu hết các trường hợp mà không có bất kỳ JS cũng như gobs CSS. Nếu bạn cần áp dụng các hình ảnh khác nhau ở các vị trí khác nhau, chỉ cần phân biệt với một lớp:.my-special-case img:before { ...


3
Theo ý kiến ​​của tôi. Đây là câu trả lời tốt hơn. Đây là quirksmodes đảm nhận onerror ..... có vẻ khá an toàn với tôi. quirksmode.org/dom/events/error.html#t01
n0nag0n

12
BTW, nếu error.jpg không tồn tại, điều này gây ra một vòng lặp vô hạn vì nó tiếp tục cố gắng tìm hình ảnh, sau đó onError được gọi lại, nó không thể tìm thấy nó và toàn bộ mọi thứ bắt đầu lại.
borq

30
Để tránh rủi ro vòng lặp vô hạn, chỉ cần thêm một bài kiểm tra: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
jacquarg

21
Ngoài ra, bạn có thể viết:onerror="this.src='error.jpg';this.onerror='';"
Denilson Sá Maia

6
JQuery ở đâu trong này?
Praveen Kumar Purushothaman

64

Tìm thấy giải pháp này trong Spring in Action 3rd Ed.

<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />

Cập nhật: Đây không phải là giải pháp chỉ dành cho HTML ... onerrorlà javascript


3
Điều này làm việc tuyệt vời. Đây là bản cập nhật với hình ảnh dự phòng trên imgur: <img src = "a-thiếu-image.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
arpo

15

<img style="background-image: url(image1), url(image2);"></img>                                            

Sử dụng hình nền cho phép bạn thêm nhiều hình ảnh. Trường hợp của tôi: image1 là hình ảnh chính, điều này sẽ nhận được từ một nơi nào đó (trình duyệt thực hiện một yêu cầu) image2 là một hình ảnh cục bộ mặc định để hiển thị trong khi image1 đang được tải. Nếu image1 trả về bất kỳ loại lỗi nào, người dùng sẽ không thấy bất kỳ thay đổi nào và điều này sẽ rõ ràng cho trải nghiệm người dùng



Điều này chỉ hoạt động nếu image1 hoàn toàn mờ đục. Nếu nó có độ trong suốt, giống như hầu hết các hình ảnh biểu tượng, thì image2 sẽ hiển thị thông qua.
vui vẻ

14
<style type="text/css">
img {
   background-image: url('/images/default.png')
}
</style>

Hãy chắc chắn nhập kích thước của hình ảnh và cho dù bạn muốn hình ảnh xếp gạch hay không.


28
Không phải hầu hết các trình duyệt hiển thị hình ảnh 'liên kết bị hỏng' khi không tìm thấy hình ảnh ... Trong trường hợp đó, việc đặt nền sẽ không giải quyết được vấn đề.
Justin D.

13

Tôi không nghĩ có thể chỉ sử dụng HTML. Tuy nhiên, sử dụng javascript, điều này có thể thực hiện được. Bassicly chúng tôi lặp qua từng hình ảnh, kiểm tra xem nó đã hoàn thành chưa và nếu nó tự nhiên là 0 thì điều đó có nghĩa là nó không được tìm thấy. Đây là mã:

fixBrokenImages = function( url ){
    var img = document.getElementsByTagName('img');
    var i=0, l=img.length;
    for(;i<l;i++){
        var t = img[i];
        if(t.naturalWidth === 0){
            //this image is broken
            t.src = url;
        }
    }
}

Sử dụng nó như thế này:

 window.onload = function() {
    fixBrokenImages('example.com/image.png');
 }

Đã thử nghiệm trong Chrome và Firefox


2
Nó hoạt động Pim, và nó hoàn toàn có thể tái sử dụng, nhưng tôi thích tùy chọn nhẹ hơn cho trường hợp này. Cảm ơn rất nhiều :) +1
Galilyou

Bạn đã cứu cả đời tôi ạ.
Beardminator

12

Nếu bạn đang sử dụng Angular / jQuery thì điều này có thể giúp ...

<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">

Giải trình

Giả sử itemcó một thuộc tính urlcó thể là null, khi đó thì hình ảnh sẽ hiển thị dưới dạng bị hỏng. Điều đó kích hoạt thực thi onerrorbiểu thức thuộc tính, như được mô tả ở trên. Bạn cần ghi đè srcthuộc tính như được mô tả ở trên, nhưng bạn sẽ cần jQuery để truy cập altSrc của bạn. Không thể làm cho nó hoạt động với JavaScript vanilla.

Có vẻ hơi hack nhưng đã lưu lại ngày trong dự án của tôi.


11

một phần tử img đơn giản không linh hoạt lắm nên tôi đã kết hợp nó với một phần tử hình ảnh. Bằng cách này, không cần CSS. khi xảy ra lỗi, tất cả các srcset được đặt thành phiên bản dự phòng. một hình ảnh liên kết bị hỏng không hiển thị. nó không tải các phiên bản hình ảnh không cần thiết. yếu tố hình ảnh hỗ trợ thiết kế đáp ứng và nhiều dự phòng cho các loại không được trình duyệt hỗ trợ.

<picture>
    <source id="s1" srcset="image1_not_supported_by_browser.webp" type="image/webp">
    <source id="s2" srcset="image2_broken_link.png" type="image/png">
    <img src="image3_fallback.jpg" alt="" onerror="this.onerror=null;document.getElementById('s1').srcset=document.getElementById('s2').srcset=this.src;">
</picture>

cái này thật tuyệt lưu ý việc thiếu hỗ trợ trình duyệt caniuse.com/#feat=picture . xem xét sử dụng polyfill hoặc giải pháp khác nếu bạn cần hỗ trợ các trình duyệt cũ hơn như IE11.
Hinrich

7

góc2:

<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">

1
Trong khi điều này có thể hoạt động tôi không nghĩ rằng nó thêm bất kỳ thông tin mới. Phần onerror chỉ là JavaScript vanilla và liên kết src nên được người dùng Angular biết đến
Chic

7

Giải pháp đơn giản và gọn gàng liên quan đến một số câu trả lời tốt và bình luận.

<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">

Nó thậm chí giải quyết rủi ro vòng lặp vô hạn.

Đã làm cho tôi.


IMO, điều này chắc chắn không có vẻ thanh lịch.
Script47

1
@ Script47 Thật gọn gàng, tôi nhắc lại gọn gàng
manish kumar

1
Không, tôi cũng sẽ không nói nó gọn gàng. Chưa kể rằng đây có lẽ là một sự thử nghiệm lại các giải pháp khác.
Script47

Hoạt động như một lá bùa! Cảm ơn bạn!
Goehy điều chỉnh

1
Phao cứu sinh. Tôi không muốn thanh lịch, tôi muốn đơn giản và làm việc. Cảm ơn!
Bộ

7

Một giải pháp duy nhất cho HTML, trong đó yêu cầu duy nhất là bạn biết kích thước của hình ảnh mà bạn đang chèn. Sẽ không hoạt động đối với hình ảnh trong suốt, vì nó sử dụng background-imagelàm phụ.

Chúng ta có thể sử dụng thành công background-imageđể liên kết hình ảnh xuất hiện nếu hình ảnh đã cho bị thiếu. Sau đó, vấn đề duy nhất là hình ảnh biểu tượng bị hỏng - chúng ta có thể loại bỏ nó bằng cách chèn một ký tự trống rất lớn, do đó đẩy nội dung ra ngoài màn hình img.

img {
  background-image: url("http://placehold.it/200x200");
  overflow: hidden;
}

img:before {
  content: " ";
  font-size: 1000px;
}
This image is missing:
<img src="a.jpg" style="width: 200px; height: 200px"/><br/>
And is displaying the placeholder


Một giải pháp chỉ CSS (chỉ dành cho Webkit)

img:before {
  content: " ";
  font-size: 1000px;
  background-image: url("http://placehold.it/200x200");
  display: block;
  width: 200px;
  height: 200px;
  position: relative;
  z-index: 0;
  margin-bottom: -16px;
}
This image is there:
<img src="http://placehold.it/100x100"/><br/>

This image is missing:
<img src="a.jpg"/><br/>
And is displaying the placeholder


4

Không có cách nào để chắc chắn vô số khách hàng (trình duyệt) sẽ cố gắng xem trang của bạn. Một khía cạnh cần xem xét là các ứng dụng email khách là các trình duyệt web không chính xác và có thể không xử lý các trò lừa bịp như vậy ...

Vì vậy, bạn C ALNG nên bao gồm một alt / văn bản với WIDTH WIDTH và HEIGHT, như thế này. Đây là một giải pháp HTML thuần túy.

alt="NO IMAGE" width="800" height="350"

Vì vậy, câu trả lời tốt khác sẽ được sửa đổi một chút như sau:

<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">

Tôi gặp vấn đề với thẻ đối tượng trong Chrome, nhưng tôi sẽ tưởng tượng điều này cũng sẽ áp dụng cho điều đó.

Bạn có thể định kiểu thêm cho alt / văn bản RẤT LỚN ...

Vì vậy, câu trả lời của tôi là sử dụng Javascript với một dự phòng alt / văn bản đẹp.

Tôi cũng thấy điều này thú vị: Cách tạo kiểu cho thuộc tính alt của hình ảnh


3

Một phiên bản có thể sửa đổi với JQuery , hãy thêm phiên bản này vào cuối tệp của bạn:

<script>
    $(function() {
        $('img[data-src-error]').error(function() {
            var o = $(this);
            var errorSrc = o.attr('data-src-error');

            if (o.attr('src') != errorSrc) {
                o.attr('src', errorSrc);
            }
        });
    });
</script>

và trên imgthẻ của bạn :

<img src="..." data-src-error="..." />

3

Các giải pháp trên là không đầy đủ , nó bỏ lỡ thuộc tính src.

this.srcthis.attribute('src')KHÔNG giống nhau, ví dụ đầu tiên chứa tham chiếu đầy đủ đến hình ảnh http://my.host/error.jpg, nhưng thuộc tính chỉ giữ giá trị ban đầu,error.jpg

Giải pháp đúng

<img src="foo.jpg" onerror="if (this.src != 'error.jpg' && this.attribute('src') != 'error.jpg') this.src = 'error.jpg';" />

3
Khi sử dụng mã này, tôi thấy Uncaught TypeError: this.attribute is not a functiontrong Chrome 43.
John Washam 01/07/2015

Bạn đang sử dụng jQuery?
mix3d

onError không được chấp nhận theo nhà phát
triển.mozilla.org/en

2

Nếu bạn đang sử dụng Angular 1.x, bạn có thể bao gồm một lệnh sẽ cho phép bạn dự phòng bất kỳ số lượng hình ảnh nào. Thuộc tính dự phòng hỗ trợ một url, nhiều url trong một mảng hoặc biểu thức góc sử dụng dữ liệu phạm vi:

<img ng-src="myFirstImage.png" fallback="'fallback1.png'" />
<img ng-src="myFirstImage.png" fallback="['fallback1.png', 'fallback2.png']" />
<img ng-src="myFirstImage.png" fallback="myData.arrayOfImagesToFallbackTo" />

Thêm một chỉ thị dự phòng mới vào mô-đun ứng dụng góc cạnh của bạn:

angular.module('app.services', [])
    .directive('fallback', ['$parse', function ($parse) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var errorCount = 0;

                // Hook the image element error event
                angular.element(element).bind('error', function (err) {
                    var expressionFunc = $parse(attrs.fallback),
                        expressionResult,
                        imageUrl;

                    expressionResult = expressionFunc(scope);

                    if (typeof expressionResult === 'string') {
                        // The expression result is a string, use it as a url
                        imageUrl = expressionResult;
                    } else if (typeof expressionResult === 'object' && expressionResult instanceof Array) {
                        // The expression result is an array, grab an item from the array
                        // and use that as the image url
                        imageUrl = expressionResult[errorCount];
                    }

                    // Increment the error count so we can keep track
                    // of how many images we have tried
                    errorCount++;
                    angular.element(element).attr('src', imageUrl);
                });
            }
        };
    }])

Ý tưởng tuyệt vời! Một mảng tắt hình ảnh dự phòng là một triển khai tốt
Z. Khullah

1

Gần đây tôi đã phải xây dựng một hệ thống dự phòng bao gồm bất kỳ số lượng hình ảnh dự phòng. Đây là cách tôi đã làm bằng cách sử dụng một hàm JavaScript đơn giản.

HTML

<img src="some_image.tiff"
    onerror="fallBackImg(this);"
    data-fallIndex="1"
    data-fallback1="some_image.png"
    data-fallback2="some_image.jpg">

JavaScript

function fallBackImg(elem){
    elem.onerror = null;
    let index = +elem.dataset.fallIndex;
    elem.src = elem.dataset[`fallback${index}`];
    index++;
    elem.dataset.fallbackindex = index;
}

Tôi cảm thấy như đó là một cách khá nhẹ để xử lý nhiều hình ảnh dự phòng.


onError không được chấp nhận theo nhà phát
triển.mozilla.org/en

0

Sử dụng Jquery bạn có thể làm một cái gì đó như thế này:

$(document).ready(function() {
    if ($("img").attr("src") != null)
    {
       if ($("img").attr("src").toString() == "")
       {
            $("img").attr("src", "images/default.jpg");
       }
    }
    else
    {
        $("img").attr("src", "images/default.jpg");
    }
});

0

Đối với bất kỳ hình ảnh, chỉ cần sử dụng mã javascript này:

if (ptImage.naturalWidth == 0)
    ptImage.src = '../../../../icons/blank.png';

nơi ptImagelà một <img>địa chỉ thẻ thu được bằng document.getElementById().


0

Google đã đưa ra trang này cho các từ khóa "image fallback html", nhưng vì không phải ở trên đã giúp tôi và tôi đang tìm kiếm một "hỗ trợ dự phòng svg cho IE dưới 9", tôi tiếp tục tìm kiếm và đây là những gì tôi tìm thấy:

<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->

Nó có thể lạc đề, nhưng nó đã giải quyết vấn đề của riêng tôi và nó cũng có thể giúp người khác.


0

Ngoài câu trả lời tuyệt vời của Patrick , cho những bạn đang tìm kiếm một giải pháp js góc cạnh đa nền tảng, bạn hãy vào đây:

<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
    <!-- any html as a fallback -->
</object>

Đây là một plunk nơi tôi đang chơi cố gắng tìm giải pháp phù hợp: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview


0

Nếu bạn đã tạo dự án Web động và đã đặt hình ảnh được yêu cầu trong WebContent thì bạn có thể truy cập hình ảnh bằng cách sử dụng mã được đề cập bên dưới trong Spring MVC:

<img src="Refresh.png" alt="Refresh" height="50" width="50">

Bạn cũng có thể tạo thư mục có tên img và đặt hình ảnh vào thư mục img và đặt thư mục img đó vào WebContent sau đó bạn có thể truy cập hình ảnh bằng cách sử dụng mã được đề cập bên dưới:

<img src="img/Refresh.png" alt="Refresh" height="50" width="50">

-2

Tốt!! Tôi thấy cách này thuận tiện, kiểm tra thuộc tính chiều cao của hình ảnh là 0, sau đó bạn có thể ghi đè thuộc tính src bằng hình ảnh mặc định: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageEuity/ Hình ảnh

 image.setAttribute('src','../icons/<some_image>.png');
  //check the height attribute.. if image is available then by default it will 
  //be 100 else 0
  if(image.height == 0){                                       
       image.setAttribute('src','../icons/default.png');
  }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.