การใส่รูปภาพเริ่มต้นในกรณีที่แอตทริบิวต์ src ของ html <img> ไม่ถูกต้อง?


268

มีวิธีการแสดงภาพเริ่มต้นใน<img>แท็กHTML ในกรณีที่srcคุณลักษณะไม่ถูกต้อง (ใช้ HTML เท่านั้น)? ถ้าไม่เป็นเช่นนั้นคุณจะมีวิธีการแก้ปัญหาแบบเบา ๆ อย่างไร


3
HTML ไม่มีทางเลือกสำหรับภาพที่เสียหาย คุณจะต้องใช้ JavaScript เพื่อค้นหาภาพที่เสียหายและเปลี่ยนคุณลักษณะ src ของพวกเขา
Blixt

2
@ Blixt - จะเกิดอะไรขึ้นถ้าไคลเอนต์ของคุณคือ MS Outlook หรือผู้อ่าน EMAIL บางคนและคุณไม่มี Javascript และตัวเลือกวัตถุไม่ทำงาน ... ฉันคิดว่าวิธีแก้ปัญหาเดียวคือ alt / text
Xofo

คำตอบ:


319

คุณขอวิธีแก้ปัญหา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>

เนื่องจากไม่มีภาพแรกภาพทางเลือก (sprites ที่ใช้ในเว็บไซต์นี้ *) จะแสดงขึ้น และถ้าคุณกำลังใช้จริงๆเบราว์เซอร์เก่าที่ไม่สนับสนุนobjectก็จะไม่สนใจแท็กนั้นและใช้imgแท็ก ดูเว็บไซต์caniuseเพื่อความเข้ากันได้ องค์ประกอบนี้ได้รับการสนับสนุนอย่างกว้างขวางจากเบราว์เซอร์ทั้งหมดจาก IE6 +

* นอกจาก URL สำหรับรูปภาพจะเปลี่ยน (อีกครั้ง) ซึ่งในกรณีนี้คุณอาจเห็นข้อความ alt


3
มันใช้งานได้สำหรับฉันใน IE8 หลังจากฉันใส่ DTD สำหรับ HTML 4.01
Patrick McElhaney

สิ่งนี้จะไม่ทำงานหากไม่มีภาพที่มีอยู่ X-Frame-Optionsตั้งค่าไว้SAMEORIGINหรือตั้งค่าอนุญาตมากขึ้น
อัตติลาโอ

มันทำงานได้ แต่ถ้าการเชื่อมโยงใน object.data ไม่น่าเชื่อถือก็สามารถโหลดชนิดของสิ่งทั้งหมด ...
Michael_Scharf

1
องค์ประกอบ 'img' ไม่สามารถซ้อนอยู่ใน 'วัตถุ' องค์ประกอบได้
Matheus Miranda

2
@ Mathus แน่นอนมันสามารถ ในวัตถุ HTML4 สามารถมีเนื้อหาการไหล (เกือบทุกอย่างรวมถึง img) และใน HTML5 นั้นโปร่งใสหมายความว่าสามารถมี HTML5 ที่ถูกต้องได้
Patrick McElhaney

318

มันใช้งานได้ดีสำหรับฉัน บางทีคุณอาจต้องการใช้ JQuery เพื่อขอเหตุการณ์

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

อัปเดตด้วยยามข้อผิดพลาด jacquargs

อัปเดต: CSS เฉพาะโซลูชันที่ ฉันเพิ่งเห็นVitaly Friedmanสาธิตโซลูชัน CSS ที่ยอดเยี่ยมที่ฉันไม่ทราบ แนวคิดคือการนำcontentคุณสมบัติไปใช้กับรูปภาพที่เสียหาย โดยปกติ:afterหรือ:beforeไม่ใช้กับภาพ แต่เมื่อมีการแตกจะใช้งานได้

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

การสาธิต: https://jsfiddle.net/uz2gmh2k/2/

ตามที่ซอแสดงให้เห็นว่าภาพที่เสียหายนั้นไม่ได้ถูกลบออกไป แต่สิ่งนี้อาจจะแก้ปัญหาสำหรับกรณีส่วนใหญ่โดยไม่มี JS หรือ gobs ของ CSS หากคุณต้องการใช้ภาพที่แตกต่างในสถานที่ต่างกันเพียงแค่แยกความแตกต่างกับชั้นเรียน:.my-special-case img:before { ...


3
ในความเห็นของฉัน. นี่คือคำตอบที่ดีกว่า ที่นี่โหมดแปลก ๆ ใช้ onerror ..... ดูเหมือนว่าค่อนข้างปลอดภัยสำหรับฉัน quirksmode.org/dom/events/error.html#t01
n0nag0n

12
BTW หาก error.jpg ไม่มีอยู่นี่จะทำให้เกิดการวนซ้ำไม่สิ้นสุดเนื่องจากพยายามค้นหารูปภาพจากนั้นจะมีการเรียก onError อีกครั้งไม่สามารถค้นหาได้และทุกสิ่งจะเริ่มต้นอีกครั้ง
borq

30
เพื่อหลีกเลี่ยงความเสี่ยงวนไม่สิ้นสุดเพียงเพิ่มการทดสอบ: <img src = "foo.jpg" onerror = "if (this.src! = 'error.jog') this.src = 'error.jpg';">
jacquarg

21
หรือคุณสามารถเขียน:onerror="this.src='error.jpg';this.onerror='';"
Denilson Sá Maia

6
jQuery อยู่ที่ไหนในนี้
Praveen Kumar Purushothaman

64

พบวิธีแก้ปัญหานี้ใน Spring in Action 3rd Ed

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

อัปเดต: นี่ไม่ใช่วิธีแก้ปัญหา HTML เท่านั้น ... onerrorคือจาวาสคริปต์


3
มันใช้งานได้ดี นี่คือการอัปเดตด้วยภาพทางเลือกใน imgur: <img src = "a-missing-image.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
arpo

15

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

ใช้ภาพพื้นหลังที่ให้คุณเพิ่มหลายภาพ กรณีของฉัน: image1 เป็นภาพหลักซึ่งจะได้รับจากบางสถานที่ (เบราว์เซอร์ที่ทำคำขอ) image2 เป็นภาพในระบบเริ่มต้นที่จะแสดงในขณะที่โหลด image1 หาก image1 ส่งคืนข้อผิดพลาดใด ๆ ผู้ใช้จะไม่เห็นการเปลี่ยนแปลงใด ๆ และสิ่งนี้จะสะอาดสำหรับประสบการณ์ของผู้ใช้



ใช้งานได้เฉพาะในกรณีที่ image1 ทึบแสงสมบูรณ์ หากมีความโปร่งใสเหมือนภาพไอคอนส่วนใหญ่แล้ว image2 จะปรากฏขึ้น
jdunning

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

ตรวจสอบให้แน่ใจว่าได้ป้อนขนาดของภาพและไม่ว่าคุณต้องการให้ภาพเรียงต่อกันหรือไม่


28
เบราว์เซอร์ส่วนใหญ่ไม่แสดงรูปภาพ 'ลิงค์เสีย' เมื่อไม่พบรูปภาพ ... ในกรณีนี้การตั้งค่าพื้นหลังจะไม่สามารถแก้ปัญหาได้
Justin D.

13

ฉันไม่คิดว่าเป็นไปได้ที่จะใช้เพียง HTML อย่างไรก็ตามการใช้จาวาสคริปต์ควรจะทำได้ เราวนรอบรูปภาพแต่ละภาพอย่างถี่ถ้วนลองทดสอบดูว่ามันสมบูรณ์หรือไม่และถ้าเป็นธรรมชาติความกว้างนั้นเป็นศูนย์นั่นหมายความว่าไม่พบ นี่คือรหัส:

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;
        }
    }
}

ใช้มันแบบนี้:

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

ทดสอบใน Chrome และ Firefox


2
มันใช้งาน Pim และสามารถนำกลับมาใช้ใหม่ได้ทั้งหมด แต่ฉันต้องการตัวเลือกที่มีน้ำหนักเบาสำหรับเคสนี้ ขอบคุณมาก :) +1
Galilyou

คุณช่วยชีวิตฉันให้รอด
Beardminator

12

หากคุณใช้ Angular / jQuery นี่อาจช่วย ...

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

คำอธิบาย

สมมติว่าitemมีคุณสมบัติurlที่อาจเป็นโมฆะเมื่อเป็นแล้วภาพจะปรากฏขึ้นว่าเสีย นั่นเป็นต้นเหตุของการประมวลonerrorผลการแสดงออกของคุณลักษณะ คุณต้องแทนที่srcคุณลักษณะดังที่อธิบายไว้ข้างต้น แต่คุณจะต้อง jQuery เพื่อเข้าถึง altSrc ของคุณ ไม่สามารถทำให้มันทำงานกับวานิลลา JavaScript

อาจดูเหมือนแฮ็กเล็กน้อย แต่บันทึกวันไว้ในโครงการของฉัน


11

องค์ประกอบ img อันเรียบง่ายนั้นไม่ยืดหยุ่นมากดังนั้นฉันจึงรวมเข้ากับองค์ประกอบภาพ วิธีนี้ไม่จำเป็นต้องใช้ CSS เมื่อเกิดข้อผิดพลาด srcset ทั้งหมดจะถูกตั้งค่าเป็นเวอร์ชันสำรอง รูปภาพลิงค์ที่ใช้งานไม่ได้แสดงขึ้นมา มันไม่โหลดรุ่นภาพที่ไม่จำเป็น องค์ประกอบภาพรองรับการออกแบบที่ตอบสนองและหลายทางเลือกสำหรับประเภทที่เบราว์เซอร์ไม่รองรับ

<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>

อันนี้ดีมาก! จะตระหนักถึงหายไปเบราว์เซอร์สนับสนุนcaniuse.com/#feat=picture พิจารณาใช้ polyfill หรือโซลูชันอื่นหากคุณต้องการสนับสนุนเบราว์เซอร์รุ่นเก่าเช่น IE11
Hinrich

7

angular2:

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

1
ขณะนี้อาจใช้งานได้ฉันไม่คิดว่ามันจะเพิ่มข้อมูลใหม่ ส่วน onerror เป็นเพียงแค่วานิลลาจาวาสคริปต์และผู้ใช้แองกูลาร์ควรรู้จักการเชื่อมโยง src แล้ว
Chic

7

วิธีการแก้ปัญหาที่เรียบง่ายและเรียบร้อยเกี่ยวข้องกับคำตอบและความคิดเห็นที่ดี

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

มันยังแก้ปัญหาความเสี่ยงแบบไม่ จำกัด

ทำงานให้ฉัน


IMO นี้ดูไม่หรูหราอย่างแน่นอน
Script47

1
@ Script47 มันเรียบร้อยฉันพูดซ้ำเรียบร้อย
มานอมคูมา

1
ไม่ฉันไม่คิดว่ามันจะเรียบร้อย ไม่พูดถึงว่านี่อาจเป็นวิธีการแก้ปัญหาอื่น ๆ
Script47

ทำงานเหมือนจับใจ! ขอบคุณ!
Goehybrid

1
ผู้ช่วยชีวิต ฉันไม่ต้องการสง่างามฉันต้องการเรียบง่ายและทำงานได้ ขอบคุณ!
Kit

7

โซลูชัน HTML เท่านั้นโดยที่ข้อกำหนดเพียงอย่างเดียวคือคุณรู้ขนาดของภาพที่คุณแทรก จะไม่ทำงานสำหรับภาพที่โปร่งใสตามที่ใช้background-imageเป็นฟิลเลอร์

เราสามารถใช้background-imageเพื่อเชื่อมโยงภาพที่ปรากฏขึ้นหากภาพที่ระบุหายไป แล้วปัญหาเดียวก็คือภาพไอคอนเสีย - 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


โซลูชัน CSS เท่านั้น (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

ไม่มีวิธีที่จะตรวจสอบจำนวนลูกค้า (เบราว์เซอร์) ที่จะพยายามดูหน้าเว็บของคุณ สิ่งหนึ่งที่ต้องพิจารณาคือไคลเอนต์อีเมลเป็นเว็บเบราว์เซอร์ defacto และอาจไม่จัดการกับเคล็ดลับการหลอกลวง ...

ดังนั้นคุณควรรวม alt / text ด้วย DEFAULT WIDTH และ HEIGHT เช่นนี้ นี่เป็นโซลูชัน HTML ที่แท้จริง

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

ดังนั้นคำตอบที่ดีอื่น ๆ จะถูกแก้ไขเล็กน้อยดังนี้:

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

ฉันมีปัญหากับแท็กวัตถุใน Chrome แต่ฉันคิดว่าสิ่งนี้จะใช้ได้กับสิ่งนั้นเช่นกัน

คุณสามารถกำหนดสไตล์ alt / ข้อความเพิ่มเติมให้ใหญ่มาก ...

ดังนั้นคำตอบของฉันคือใช้ Javascript ด้วย alt / text fallback ที่ดี

ฉันก็พบสิ่งที่น่าสนใจเช่น: วิธีจัดสไตล์แอตทริบิวต์ alt ของรูปภาพ


3

เวอร์ชันที่ปรับเปลี่ยนได้ด้วยJQueryให้เพิ่มส่วนท้ายไฟล์ของคุณ:

<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>

และบนimgแท็กของคุณ:

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

3

การแก้ปัญหาข้างต้นไม่สมบูรณ์ก็พลาดคุณลักษณะsrcก็พลาดแอตทริบิวต์

this.srcและthis.attribute('src')ไม่เหมือนกันอันแรกมีการอ้างอิงแบบเต็มไปยังรูปภาพเช่นhttp://my.host/error.jpgแต่แอตทริบิวต์เพิ่งเก็บค่าดั้งเดิมไว้error.jpg

ทางออกที่ถูกต้อง

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

3
เมื่อใช้รหัสนี้ฉันเห็นUncaught TypeError: this.attribute is not a functionใน Chrome 43
John Washam

คุณใช้ jQuery อยู่หรือเปล่า?
mix3d

onError ไม่ได้รับการสนับสนุนตาม developer.mozilla.org/en-US/docs/Web/HTML/Element/img
comiventor

2

หากคุณกำลังใช้ Angular 1.x คุณสามารถรวมคำสั่งที่จะช่วยให้คุณสามารถย้อนกลับไปยังรูปภาพจำนวนเท่าใดก็ได้ แอ็ตทริบิวต์ fallback สนับสนุน url เดี่ยวหลาย URL ภายในอาร์เรย์หรือนิพจน์เชิงมุมโดยใช้ข้อมูลขอบเขต:

<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" />

เพิ่มคำสั่งทางเลือกใหม่ให้กับโมดูลแอปเชิงมุมของคุณ:

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);
                });
            }
        };
    }])

ไอเดียเด็ด ๆ ! อาเรย์ปิดภาพทางเลือกเป็นการใช้งานที่ดี
Z. Khullah

1

ฉันเพิ่งต้องสร้างระบบถอยกลับซึ่งรวมถึงภาพทางเลือกจำนวนเท่าใดก็ได้ นี่คือวิธีที่ฉันทำได้โดยใช้ฟังก์ชัน JavaScript อย่างง่าย

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;
}

ฉันรู้สึกว่ามันเป็นวิธีที่มีน้ำหนักเบามากในการจัดการกับภาพทางเลือกจำนวนมาก


onError ไม่ได้รับการสนับสนุนตามdeveloper.mozilla.org/en-US/docs/Web/HTML/Element/img
comiventor

0

การใช้ Jquery คุณสามารถทำสิ่งนี้:

$(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

สำหรับรูปภาพใด ๆ ให้ใช้รหัส javascript นี้:

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

ที่ptImageเป็นอยู่ได้โดยการแท็ก<img>document.getElementById()


0

Google ขว้างหน้านี้ไปที่คำหลัก "image fallback html" แต่เนื่องจากไม่ใช่สิ่งที่กล่าวมาช่วยฉันได้และฉันกำลังมองหา "svg fallback support สำหรับ IE ต่ำกว่า 9" ฉันจึงทำการค้นหาต่อไปและนี่คือสิ่งที่ฉันพบ:

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

อาจเป็นหัวข้อนอกเรื่อง แต่ก็แก้ไขปัญหาของฉันเองและอาจช่วยคนอื่นด้วย


0

นอกเหนือจากคำตอบที่ยอดเยี่ยมของ Patrickสำหรับผู้ที่กำลังค้นหาโซลูชัน js เชิงมุมข้ามแพลตฟอร์มคุณไปที่นี่:

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

นี่คือเสียงพึมพำที่ฉันเล่นพยายามหาวิธีแก้ปัญหาที่ถูกต้อง: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview


0

หากคุณสร้างโครงการเว็บแบบไดนามิกและวางรูปภาพที่ต้องการใน WebContent แล้วคุณสามารถเข้าถึงรูปภาพโดยใช้โค้ดด้านล่างใน Spring MVC:

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

นอกจากนี้คุณยังสามารถสร้างโฟลเดอร์ชื่อ img และวางภาพภายในโฟลเดอร์ img และวางโฟลเดอร์ img ไว้ใน WebContent จากนั้นคุณสามารถเข้าถึงรูปภาพโดยใช้รหัสที่ระบุด้านล่าง:

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

-2

ดี!! ฉันพบวิธีนี้สะดวกตรวจสอบความสูงของภาพเป็น 0 จากนั้นคุณสามารถเขียนทับแอตทริบิวต์ src ด้วยภาพเริ่มต้น: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/ ภาพ

 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');
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.