पता लगाएँ कि जब एक छवि जावास्क्रिप्ट में लोड करने में विफल रहती है


104

क्या यह निर्धारित करने का एक तरीका है कि क्या कोई छवि पथ वास्तविक छवि की ओर जाता है, अर्थात्, यह पता लगाएं कि जब जावास्क्रिप्ट में कोई छवि लोड करने में विफल हो जाती है।

एक वेब ऐप के लिए, मैं एक xml फ़ाइल पार्स कर रहा हूं और गतिशील रूप से छवि पथों की सूची से HTML छवियां बना रहा हूं। कुछ छवि पथ अब सर्वर पर मौजूद नहीं हो सकते हैं, इसलिए मैं यह पता लगाने में गर्व से विफल होना चाहता हूं कि कौन सी छवियां उस HTML ईएमजी तत्व को लोड करने और हटाने में विफल हैं।

नोट JQuery के समाधान का उपयोग नहीं किया जा सकता है (बॉस JQuery का उपयोग नहीं करना चाहता, हाँ मुझे पता है कि मुझे शुरू नहीं करना है)। मुझे पता है कि छवि खराब होने पर JQuery में एक तरीका पता है, लेकिन यह विफल रहा कि नहीं।

Img तत्वों को बनाने के लिए मेरा कोड लेकिन मैं कैसे पता लगा सकता हूं कि क्या img पथ छवि लोड करने में विफल रहता है?

var imgObj = new Image();  // document.createElement("img");
imgObj.src = src;

यह आपकी मदद कर सकता है: stackoverflow.com/questions/1977871/… (यह jQuery है, लेकिन यह अभी भी आपको सही रास्ते पर ले जा सकता है)
बेन ली

इनमें से एक google.com/…
ajax333221

2
मजेदार @ ajax333221 यह बहुत ही पहला सवाल आपके लिंक के परिणामों में है :)
SSH This

एक नया बॉस खोजने के लिए एक JQuery चयनकर्ता लिखें ... इंटरनेट एक बड़ी जगह है।
JJS

जवाबों:


115

आप निम्न कोड आज़मा सकते हैं। मैं हालांकि ब्राउज़र संगतता के लिए वाउच नहीं कर सकता, इसलिए आपको इसका परीक्षण करना होगा।

function testImage(URL) {
    var tester=new Image();
    tester.onload=imageFound;
    tester.onerror=imageNotFound;
    tester.src=URL;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

और jQuery के प्रतिरोधी मालिक के लिए मेरी सहानुभूति!


2
किसी भी विचार अगर यह बताने का कोई तरीका है कि क्या वह एक अनुप्रेषित का सामना करता है?
क्विकशिफ्टिन

4
यह webKit (एपिफेनी, सफारी, ...) पर काम नहीं करता है जो उस सर्वर पर निर्भर करता है जिससे आपको छवि मिल रही है। उदाहरण के लिए, कभी-कभी imgur एक ऐसी छवि नहीं भेजता है जो न तो मौजूद है और न ही 404 स्थिति और त्रुटि घटना इस मामले में ट्रिगर नहीं होती है।

इसके साथ समस्या यह है कि आपका संदेश, "वह छवि नहीं मिली।" प्रतिक्रिया कोड 500 या 403 या कुछ और हो सकता है। आप नहीं जानते कि यह एक 404 था। वास्तव में यह बहुत संभावना नहीं है कि यह 404 है क्योंकि आप शायद कोशिश नहीं करेंगे और एक छवि को लोड नहीं करेंगे।
PHP गुरु

1
प्रत्यक्ष
असाइनमेंट के

50

उत्तर अच्छा है, लेकिन यह एक समस्या का परिचय देता है। जब भी आप सीधे onloadया onerrorसीधे असाइन करते हैं, तो यह उस कॉलबैक को प्रतिस्थापित कर सकता है जिसे पहले सौंपा गया था। यही कारण है कि वहाँ एक अच्छा विधि यह है कि "रजिस्टरों निर्दिष्ट श्रोता EventTarget पर उस पर कहा जाता है" के रूप में वे कहते हैं कि पर MDN । आप एक ही घटना पर जितने चाहें उतने श्रोता पंजीकृत कर सकते हैं।

मुझे उत्तर को थोड़ा फिर से लिखना चाहिए।

function testImage(url) {
    var tester = new Image();
    tester.addEventListener('load', imageFound);
    tester.addEventListener('error', imageNotFound);
    tester.src = url;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

क्योंकि बाह्य संसाधन लोडिंग प्रक्रिया अतुल्यकालिक है, इसलिए यह निम्नलिखित जैसे वादों के साथ आधुनिक जावास्क्रिप्ट का उपयोग करने के लिए भी अच्छा होगा।

function testImage(url) {

    // Define the promise
    const imgPromise = new Promise(function imgPromise(resolve, reject) {

        // Create the image
        const imgElement = new Image();

        // When image is loaded, resolve the promise
        imgElement.addEventListener('load', function imgOnLoad() {
            resolve(this);
        });

        // When there's an error during load, reject the promise
        imgElement.addEventListener('error', function imgOnError() {
            reject();
        })

        // Assign URL
        imgElement.src = url;

    });

    return imgPromise;
}

testImage("http://foo.com/bar.jpg").then(

    function fulfilled(img) {
        console.log('That image is found and loaded', img);
    },

    function rejected() {
        console.log('That image was not found');
    }

);

2
शायद मुझे कुछ याद आ रहा है, लेकिन असाइनमेंट (tester.onload = ..) कॉलबैक को कैसे बदल सकता है, अगर "परीक्षक" बस बनाया गया था? यहां तक ​​कि अगर कोड का कुछ अस्पष्ट हिस्सा बनाई गई प्रत्येक छवि में एक घटना जोड़ता है, तो यह स्पष्ट नहीं है कि हम उन घटनाओं का पता लगाने के उद्देश्य से रखना चाहते हैं यदि कोई छवि मौजूद है।
jvilhena

1
आप बिल्कुल सही हैं। इस विशेष मामले में यह एक समस्या नहीं हो सकती है क्योंकि यह अत्यधिक संभावना है कि इसे प्रतिस्थापित नहीं किया जाएगा। हालांकि, सामान्य तौर पर, एक घटना श्रोता को जोड़ना सीधे एक विधि को निर्दिष्ट करने से बेहतर अभ्यास है।
emil.c

1
@JohnWeisz एरो फ़ंक्शंस गुमनाम हैं, इसलिए डिबग करना कठिन है, उन्हें सावधानी से उपयोग करें।
emil.c

10
@ जिफको मैं आपके साथ इस तरह की चर्चा जारी रखने में सहज महसूस नहीं करता। मैं आपकी भाषा से आहत महसूस करता हूं। यदि आपको लगता है कि मेरा उत्तर गलत या अपूर्ण है, तो परिवर्तन का सुझाव दें और अपने तर्क को स्पष्ट करें। यदि आपको लगता है कि कुछ BAD अभ्यास है, तो अपने स्वयं के उत्तर के साथ एक अच्छा अभ्यास सुझाएं।
emil.c

2
यहां तीर के कार्यों के बारे में चर्चा क्यों की जाती है? यह टॉपिक है। इसका उत्तर ठीक है कि यह कैसे विशेष रूप से है क्योंकि पुराने ब्राउज़र तीर कार्यों (उदाहरण के लिए इंटरनेट एक्सप्लोरर) का समर्थन नहीं करते हैं।
PHP गुरु

29

यह:

<img onerror="this.src='/images/image.png'" src="...">

1
हालांकि यह एक उपयोगी विशेषता है जिसका उपयोग छवि विफलता तकनीक के रूप में किया जा सकता है, पाठकों के लिए इसे समझने के लिए अधिक क्रिया प्रतिक्रिया उपयोगी होगी।
सोरक

1
इतना छोटा और इतना उपयोगी! केवल इसे छिपाने के लिए:<img src="your/path/that/might/fail.png" onerror="$(this).hide();"/>
J0ANMM

2
@ सोराक की टिप्पणी ने मुझे घृणा के साथ हँसाया। यह सही जवाब है।
user3751385

@ J0ANMM छवि को छुपाने का एक और तरीका एक खाली alt विशेषता जोड़ना है: <img alt = "" src = "yourpicture.png">
रिक ग्लिमर

अति उत्कृष्ट! एक छवि पर असफल होने के बजाय मैं इस पाठ को onerror = "this.alt = 'नहीं मान्य छवि, उपयोग लिंक ^" प्रिंट करता हूं
पसीने से तर

6
/**
 * Tests image load.
 * @param {String} url
 * @returns {Promise}
 */
function testImageUrl(url) {
  return new Promise(function(resolve, reject) {
    var image = new Image();
    image.addEventListener('load', resolve);
    image.addEventListener('error', reject);
    image.src = url;
  });
}

return testImageUrl(imageUrl).then(function imageLoaded(e) {
  return imageUrl;
})
.catch(function imageFailed(e) {
  return defaultImageUrl;
});

4

jg के लिए jQuery + CSS

JQuery के साथ यह मेरे लिए काम कर रहा है:

$('img').error(function() {
    $(this).attr('src', '/no-img.png').addClass('no-img');
});

और मैं अपनी वेबसाइट पर हर जगह इस चित्र का उपयोग कर सकता हूं, भले ही इसका आकार निम्नलिखित CSS3 की संपत्ति के साथ हो:

img.no-img {
    object-fit: cover;
    object-position: 50% 50%;
}

टीआईपी 1: कम से कम 800 x 800 पिक्सल के वर्ग छवि का उपयोग करें ।

टीआईपी 2: लोगों के चित्र के साथ उपयोग के लिए , उपयोग करेंobject-position: 20% 50%;

केवल बैकग्राउंड-आईएमजी के लिए सीएसएस

अनुपलब्ध पृष्ठभूमि छवियों के लिए, मैंने प्रत्येक background-imageघोषणा पर निम्नलिखित भी जोड़ा :

background-image: url('path-to-image.png'), url('no-img.png');

नोट: पारदर्शी छवियों के लिए काम नहीं कर रहा है।

अपाचे सर्वर साइड

एक अन्य उपाय यह है कि अपाचे के साथ लापता छवि का पता लगाने से पहले उसे ब्राउज़र में भेज दिया जाए और उसे डिफ़ॉल्ट रूप से नं। Img.png सामग्री से हटा दिया जाए।

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} /images/.*\.(gif|jpg|jpeg|png)$
RewriteRule .* /images/no-img.png [L,R=307]

3

यहाँ एक फ़ंक्शन है जो मैंने एक और उत्तर के लिए लिखा है: जावास्क्रिप्ट छवि यूआरएल सत्यापित करें । मैं अगर यह आप वास्तव में क्या जरूरत है पता नहीं है, लेकिन यह विभिन्न तकनीकों है कि आप प्रयोग करेंगे जिसके लिए संचालकों में शामिल हैं का उपयोग करता है onload, onerror, onabortऔर एक सामान्य समय समाप्ति।

क्योंकि छवि लोड करना अतुल्यकालिक है, आप अपनी छवि के साथ इस फ़ंक्शन को कॉल करते हैं और फिर यह परिणाम के कुछ समय बाद आपके कॉलबैक को कॉल करता है।


-19

नीचे की तरह:

var img = new Image(); 
img.src = imgUrl; 

if (!img.complete) {

//has picture
}
else //not{ 

}

3
नहीं। यह आपको कुछ ब्राउज़रों में छवि को कैश किया गया है या नहीं, इस पर कोई सुराग लगा सकता है - लेकिन लोड कॉलबैक के बिना, आप ब्राउज़र को उस छवि के लिए HTTP अनुरोध शुरू करने का मौका देने के लिए एक पल का भी इंतजार नहीं कर रहे हैं।
चेसमॉस्कल

यह सिर्फ कुछ कहने के लिए है!
हिटमैंड्स

4
छवि लोड करना अतुल्यकालिक है।
emil.c

@ emil.c यह किसी कारण से हमेशा नहीं होता है। चेसमॉस्कल (जिसे एसओ ने मुझे सूचित नहीं करने दिया ...) यह सही है - यह केवल तभी काम करता है जब जेएस निष्पादन जारी होने से पहले छवि लोड हो रही हो, जो कि जब भी कैश किया जाता है, ऐसा लगता है।
ट्रिस्टन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.