अगर जावास्क्रिप्ट / jQuery का उपयोग करके कोई छवि लोड की गई है, तो मैं कैसे निर्धारित कर सकता हूं?


85

उपयोगकर्ता की ब्राउज़र विंडो में फिट होने के लिए बड़ी छवि का आकार बदलने के लिए मैं कुछ जावास्क्रिप्ट लिख रहा हूं। (मैं दुर्भाग्य से स्रोत छवियों के आकार को नियंत्रित नहीं करता हूं।)

तो ऐसा कुछ HTML में होगा:

<img id="photo"
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />

क्या मेरे लिए यह निर्धारित करने का कोई तरीका है कि क्या टैग srcमें छवि imgडाउनलोड की गई है?

मुझे इसकी आवश्यकता है क्योंकि मैं एक समस्या में चल रहा हूं यदि $(document).ready()ब्राउज़र को छवि लोड करने से पहले निष्पादित किया जाता है। $("#photo").width()और $("#photo").height()प्लेसहोल्डर के आकार (कुल पाठ) को वापस कर देगा। मेरे मामले में यह 134 x 20 की तरह है।

अभी मैं जाँच कर रहा हूँ कि क्या फोटो की ऊँचाई 150 से कम है, और यह मानकर कि यदि यह सिर्फ पाठ है। लेकिन यह काफी हैक है, और यह टूट जाएगा अगर कोई फोटो 150 पिक्सेल से कम लंबा (मेरे विशेष मामले में संभावना नहीं है), या यदि उच्चतम पाठ 150 पिक्सेल से अधिक लंबा है (संभवतः एक छोटे ब्राउज़र विंडो पर हो सकता है) ।


संपादित करें: किसी को भी कोड देखना चाहते हैं:

$(function()
{
  var REAL_WIDTH = $("#photo").width();
  var REAL_HEIGHT = $("#photo").height();

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()
  {
    if(REAL_HEIGHT < 150)
    {
      REAL_WIDTH = $("#photo").width();
      REAL_HEIGHT = $("#photo").height();
      if(REAL_HEIGHT < 150)
      {
        //image not loaded.. try again in a quarter-second
        setTimeout(adjust_photo_size, 250);
        return;
      }
    }

    var new_width = . . . ;
    var new_height = . . . ;

    $("#photo").width(Math.round(new_width));
    $("#photo").height(Math.round(new_height));
  }

});

अपडेट : सुझावों के लिए धन्यवाद। यदि मुझे इस $("#photo").loadघटना के लिए कॉलबैक सेट किया जाता है, तो घटना का कोई जोखिम नहीं है , इसलिए मैंने सीधे छवि टैग पर एक ऑनलाड घटना को परिभाषित किया है। रिकॉर्ड के लिए, यहां वह कोड है जिसे मैंने समाप्त किया है:

<img id="photo"
     onload="photoLoaded();"
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />

फिर जावास्क्रिप्ट में:

//This must be outside $() because it may get called first
var isPhotoLoaded = false;
function photoLoaded()
{
  isPhotoLoaded = true;
}

$(function()
{
  //Hides scrollbars, so we can resize properly.  Set with JS instead of
  //  CSS so that page doesn't break with JS disabled.
  $("body").css("overflow", "hidden");

  var REAL_WIDTH = -1;
  var REAL_HEIGHT = -1;

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()
  {
    if(!isPhotoLoaded)
    {
      //image not loaded.. try again in a quarter-second
      setTimeout(adjust_photo_size, 250);
      return;
    }
    else if(REAL_WIDTH < 0)
    {
      //first time in this function since photo loaded
      REAL_WIDTH = $("#photo").width();
      REAL_HEIGHT = $("#photo").height();
    }

    var new_width = . . . ;
    var new_height = . . . ;

    $("#photo").width(Math.round(new_width));
    $("#photo").height(Math.round(new_height));
  }

});

1
यह बहुत पुराना है और आप पहले से ही एक उत्तर को स्वीकार कर चुके हैं, इसलिए मैं यहां टिप्पणी करूंगा। आप jQuery प्लगइन 'onImagesLoad' का उपयोग क्यों नहीं कर सकते? और यह भी, jQuery या नहीं, जावास्क्रिप्ट के साथ सेटिंग max-widthऔर max-heightछवि स्टाइल में क्या गलत है? तब आप उस सभी कोड से बचते हैं, जिसे आपको व्यूपोर्ट की चौड़ाई / ऊंचाई के आकार में अधिकतम चौड़ाई / ऊँचाई सेट करके लिखने की आवश्यकता होती है।

@ jon.wd7: मैं उस प्लगइन से परिचित नहीं हूँ, और यह '08 'में वापस नहीं आ सकता है। अधिकतम-चौड़ाई और अधिकतम-ऊँचाई, दो चीजों के लिए: 1) वे IE में समर्थित नहीं हैं (वैसे मैं IE 8 के बारे में निश्चित नहीं हूं); 2) अगर व्यूपोर्ट का आकार बदलता है (विंडो का आकार बदला जाता है, आदि) तो मुझे अभी भी अधिकतम-चौड़ाई / अधिकतम-ऊँचाई बदलने के लिए जावास्क्रिप्ट की आवश्यकता होगी (हालाँकि मैं पिक्सेल माप के बजाय "100%" का उपयोग नहीं कर सकता)
किप

यह निश्चित रूप से IE7 और IE8 में, quirksmode.org के अनुसार समर्थित है। इसलिए मुझे आपके मुद्दे पर यकीन नहीं है। मैं व्यक्तिगत रूप से इस तरह की छोटी चीज़ों के लिए IE6 का समर्थन नहीं करता हूं, इसलिए वे जो देखेंगे वह वही है जो जेएस सक्षम के बिना एक उपयोगकर्ता देखेगा। और निश्चित रूप से आपको रीसेट करने max-widthऔर max-heightआकार बदलने की आवश्यकता होगी । लेकिन यह काफी आसान काम है, .resize()वास्तव में एक-लाइनर का उपयोग करना ।

3
पूरा संपत्ति जानते हुए भी कि क्या छवि के लोड होने की अनिवार्यता रास्ता देती है।
बोरिसऑकुंस्की

1
@ एड्रियन, मोज़िला अब एंडॉइड (अज्ञात) को छोड़कर सभी प्रमुख ब्राउज़रों द्वारा समर्थित के रूप में पूरा दिखाता है
ओलिवर बॉक

जवाबों:


33

या तो एक ईवेंट श्रोता जोड़ें, या छवि को ऑनलोड के साथ स्वयं की घोषणा करें। फिर वहां से आयामों का पता लगाएं।

<img id="photo"
     onload='loaded(this.id)'
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />

कल्पना के अनुसार, ओन्डलोड केवल शरीर और फ़्रेमसेट तत्वों के लिए एक घटना है; उस ने कहा, मुझे लगता है कि यह IE में काम करता है, लेकिन मुझे नहीं पता कि यह किसी भी अन्य ब्राउज़रों में काम करता है या यह कुछ ऐसा है जिसे आप मान सकते हैं ... मैं बस कुछ हफ़्ते पहले यह देख रहा था ...
जेसन

मैंने इसे IE6, IE7, FF3, Opera9, Safair (विंडोज बीटा), और क्रोम (विंडोज बीटा) में परीक्षण किया है।
किप

9
संदेश व्यवहार और सामग्री को हतोत्साहित किया जाता है। घटनाओं को जावास्क्रिप्ट का उपयोग करके लागू किया जाना चाहिए, HTML में नहीं।
dionyziz

10
उनकी टिप्पणी आईएस से प्रासंगिक है क्योंकि हम 2008 में नहीं अटक रहे हैं। लोग अभी भी इसे पढ़ते हैं, और यहां तक ​​कि यह 08 में बुरा अभ्यास नहीं माना जाता था, आप नहीं चाहते कि लोग अब इसके अच्छे अभ्यास के बारे में सोचें।
स्पोकेन

3
document.querySelector ("img")। addEventListener ("लोड", फ़ंक्शन () {चेतावनी ('लोड!');});
फ्रैंक श्वेतेरमैन

14

Jquery डेटा स्टोर का उपयोग करके आप 'लोडेड' स्थिति को परिभाषित कर सकते हैं।

<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />

फिर कहीं और आप कर सकते हैं:

if ($('#myimage').data('loaded')) {
    // loaded, so do stuff
}

2
अन्य पुस्तकालयों के साथ बेहतर संगतता jQuery(this)के $(this)लिए उपयोग करें (jquery $ का मालिक नहीं है), खासकर जब आपके पास HTML में जावास्क्रिप्ट है।
जॉन मैग्नोलिया

11

सही उत्तर, event.special.load का उपयोग करना है

यह संभव है कि अगर ब्राउजर कैश से छवि लोड की जाती है तो लोड ईवेंट ट्रिगर नहीं होगा। इस संभावना को ध्यान में रखते हुए, हम एक विशेष लोड घटना का उपयोग कर सकते हैं जो छवि तैयार होने पर तुरंत फायर करती है। event.special.load वर्तमान में एक प्लगइन के रूप में उपलब्ध है।

। डॉक्स पर प्रति .लोड ()


2
मैं इस तरह से एक सुझाव के साथ एक जवाब जोड़ने जा रहा था, खुशी है कि मैंने इस जवाब को कोड करने से पहले देखा। असल में, हैंडलर सेट करने से पहले छवि लोड होने पर आपके हैंडलर को पहले जांचना होगा। यदि यह पहले से ही लोड है, तो कॉलबैक को तुरंत फायर करें। यह क्या $.readyहै मैं केवल चौड़ाई की जाँच करने का सुझाव देने जा रहा था, लेकिन इसकी समस्याएं हैं, मुझे वास्तव में वह समाधान पसंद है।
जुआन मेंडेस

5

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

पहुँच के संदर्भ में, क्या आपकी साइट अभी भी जावास्क्रिप्ट के बिना लोगों के लिए काम करेगी? आप अपने टैग को चलाने के लिए img टैग को सही src दे सकते हैं, अपने js को चलाने के लिए डोम रेडर को संलग्न कर सकते हैं: इमेज src को साफ़ करें (पृष्ठ फ़्लिकरिंग को रोकने के लिए css के साथ एक निश्चित और ऊँचाई दें), फिर अपना img हैंडलर सेट करें, फिर सही फ़ाइल के लिए src रीसेट करें। इस तरह आप सभी आधारों को कवर करते हैं :)


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

4

अपने मूल प्रश्न के हालिया टिप्पणियों में से एक के अनुसार

$(function() {

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()  {
    if (!$("#photo").get(0).complete) {
       $("#photo").load(function() {
          adjust_photo_size();
       });
    } else {
      ... 
    }
});

चेतावनी यह उत्तर ie8 और लोअर में एक गंभीर लूप का कारण बन सकता है, क्योंकि img.complete हमेशा ब्राउज़र द्वारा ठीक से सेट नहीं किया जाता है। यदि आपको ie8 का समर्थन करना चाहिए, तो छवि को लोड करने के लिए ध्वज का उपयोग करें।


इसे पकड़ो। यह उत्तर ie8 और लोअर में एक गंभीर लूप का कारण बन सकता है, क्योंकि img.complete हमेशा ब्राउज़र द्वारा ठीक से सेट नहीं किया जाता है। यदि आपको ie8 का समर्थन करना चाहिए, तो छवि को लोड करने के लिए ध्वज का उपयोग करें।
11

2

कुछ इस तरह का प्रयास करें:

$("#photo").load(function() {
    alert("Hello from Image");
});

6
धन्यवाद। हालांकि, इस बात की संभावना है कि ऐसा होने से पहले ही छवि लोड हो गई हो, जिस स्थिति में लोड घटना को निकाल नहीं दिया जाएगा।
किप

छवि टैग के ठीक बाद इस घटना को सेट करने वाले स्क्रिप्ट टैग के बारे में कैसे? तैयार उपयोग करने का कारण यह सुनिश्चित करना है कि संपूर्ण दस्तावेज़ लोड किया गया है, जो इस मामले में अनावश्यक है, है ना?
जेसन गोएमाट

2

एक jQuery प्लगइन है, जिसे "imagesLoaded" कहा जाता है जो एक तत्व की छवि (ओं) को लोड करने के लिए जाँच करने के लिए एक क्रॉस-ब्राउज़र संगत विधि प्रदान करता है।

साइट: https://github.com/desandro/imagesloaded/

कंटेनर के लिए उपयोग जिसमें कई चित्र हैं:

$('container').imagesLoaded(function(){
 console.log("I loaded!");
})

प्लगइन बहुत अच्छा है:

  1. अंदर कई छवियों के साथ एक कंटेनर की जाँच के लिए काम करता है
  2. यह देखने के लिए कि क्या यह लोड किया गया है एक img की जाँच के लिए काम करता है

लगता है थोड़े भारी 5KB केवल img लोड की जाँच करने के लिए छोटा। एक आसान लाइटर विधि उपलब्ध होनी चाहिए ...
cdalxndr

1

इस पर कोई टिप्पणी?

...

doShow = function(){
  if($('#img_id').attr('complete')){
    alert('Image is loaded!');
  } else {
    window.setTimeout('doShow()',100);
  }
};

$('#img_id').attr('src','image.jpg');

doShow();

...

हर जगह काम करता है ...


यह प्रयोग करने के लिए बुरा अभ्यास हैsetTimeout
cdalxndr

1

मैंने अभी jQuerys Deferred ऑब्जेक्ट का उपयोग करके एक छवि लोड करने के लिए एक jQuery फ़ंक्शन बनाया है जो लोड / त्रुटि घटना पर प्रतिक्रिया करना बहुत आसान बनाता है:

$.fn.extend({
    loadImg: function(url, timeout) {
        // init deferred object
        var defer = $.Deferred(),
            $img = this,
            img = $img.get(0),
            timer = null;

        // define load and error events BEFORE setting the src
        // otherwise IE might fire the event before listening to it
        $img.load(function(e) {
            var that = this;
            // defer this check in order to let IE catch the right image size
            window.setTimeout(function() {
                // make sure the width and height are > 0
                ((that.width > 0 && that.height > 0) ? 
                    defer.resolveWith : 
                    defer.rejectWith)($img);
            }, 1);
        }).error(function(e) {
            defer.rejectWith($img);
        });

        // start loading the image
        img.src = url;

        // check if it's already in the cache
        if (img.complete) {
            defer.resolveWith($img);
        } else if (0 !== timeout) {
            // add a timeout, by default 15 seconds
            timer = window.setTimeout(function() {
                defer.rejectWith($img);
            }, timeout || 15000);
        }

        // return the promise of the deferred object
        return defer.promise().always(function() {
            // stop the timeout timer
            window.clearTimeout(timer);
            timer = null;
            // unbind the load and error event
            this.off("load error");
        });
    }
});

उपयोग:

var image = $('<img />').loadImg('http://www.google.com/intl/en_com/images/srpr/logo3w.png')
.done(function() {
    alert('image loaded');
    $('body').append(this);
}).fail(function(){
    alert('image failed');
});

इसे यहां देखें: http://jsfiddle.net/roberkules/AdWZj/


वह अद्भुत लग रहा है। जब आपका कोड img.onload और img.onerror के लिए बेहतर हो, तो क्या आप इसका सटीक उदाहरण दे सकते हैं? क्या आपका कोड केवल jQuery त्रुटि से निपटने की कमियों को संभालने के लिए था, जिसके बारे में मुझे सूचित किया गया था: यदि फ़ाइल एक्सटेंशन नहीं है, तो IE में यह त्रुटि ट्रिगर नहीं होती है?
mplungjan

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

1
@ तो टाइमआउट केवल एक कमबैक होना चाहिए। अधिकांश ब्राउज़रों को एक ऐसी errorघटना को आग में झोंकना चाहिए जो उसके द्वारा नियंत्रित की जाती है .error(function(e) { defer.rejectWith($img); })। यदि आप jsFiddle को देखते हैं, तो आप देखेंगे कि http://www.google.com/abc.png not foundपाठ तुरंत परिणाम फलक में दिखाया गया है (टाइमआउट की प्रतीक्षा नहीं कर रहा है, क्योंकि त्रुटि घटना में किक हुई है)
roberkules

ध्यान दें कि बढ़ाने के लिए jquery के लिए। दो चीजें होनी चाहिए 1. संभाल लेकिन त्रुटि खड़ी होने से पहले सेट करें। 2. .or केवल http प्रोटोकॉल को हैंडल करता है और फाइल नहीं: // तो आप वहाँ त्रुटि नहीं प्राप्त करेंगे ..
oak

मेरे कोड उदाहरण में सफलता / त्रुटि हैंडलर को उसी कारण से src विशेषता निर्दिष्ट करने से पहले सेट किया जाता है। file://प्रतिबंध के बारे में - मुझे फ़ाइल प्रोटोकॉल का उपयोग करके छवियों को लिंक करने की कभी आवश्यकता नहीं थी और मुझे नहीं लगता कि इसकी बहुत आवश्यकता है।
रॉबर्कुल्स 15

1

यह फ़ंक्शन जाँचता है कि क्या मापने योग्य आयामों के आधार पर एक छवि लोड की गई है। यह तकनीक तब उपयोगी होती है जब कुछ स्क्रिप्ट पहले से लोड होने के बाद आपकी स्क्रिप्ट निष्पादित हो रही हो।

imageLoaded = function(node) {
    var w = 'undefined' != typeof node.clientWidth ? node.clientWidth : node.offsetWidth;
    var h = 'undefined' != typeof node.clientHeight ? node.clientHeight : node.offsetHeight;
    return w+h > 0 ? true : false;
};

मुझे पता चला कि इस समाधान की आवश्यकता हो सकती है कि छवि पर कोई मार्जिन या पैडिंग न हो, और एक खाली स्ट्रिंग का पूर्ण पाठ प्रदान किया जाता है। हालांकि ज्यादातर मामलों में, यह इरादा के अनुसार काम करता है। यह केवल तभी विफल होगा जब अनलोड की गई छवि का आकार शून्य से बड़ा हो।
राल्फ रिटोच

1

मैंने पाया कि यह मेरे लिए काम कर रहा है

document.querySelector("img").addEventListener("load", function() { alert('onload!'); });

फ्रैंक श्वेतेरमैन को श्रेय जाता है, जिन्होंने स्वीकृत जवाब पर टिप्पणी की। मुझे यहाँ लगाना पड़ा, यह बहुत मूल्यवान है ...


0

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

$(elem).onload = function() {
    doSomething();
}

लेकिन यह IE9 के लिए एक संभावित विषय है!

केवल ब्राउज़र पर हमने मुद्दों की सूचना दी थी IE9। क्या हम हैरान नहीं हैं? ऐसा लगता है कि समस्या को हल करने का सबसे अच्छा तरीका छवि पर एक src असाइन नहीं करना है जब तक कि एफ़लोड पर फ़ंक्शन को परिभाषित नहीं किया गया है, जैसे:

$(elem).onload = function() {
    doSomething();
}
$(elem).attr('src','theimage.png');

ऐसा लगता है कि IE 9 कभी-कभी फेंक नहीं देगा onload भी कारण घटना को । इस पृष्ठ पर अन्य समाधान (जैसे कि इवान कैरोल से उदाहरण के लिए) अभी भी काम नहीं किया। तार्किक रूप से, जाँच की गई कि यदि लोड स्थिति पहले से ही सफल थी और फ़ंक्शन को ट्रिगर किया गया था और यदि यह नहीं था, तो ऑनलोड हैंडलर सेट करें, लेकिन तब भी जब आप ऐसा करते हैं कि हमने परीक्षण में दिखाया कि छवि उन दो पंक्तियों के बीच लोड हो सकती है जिससे पहली पंक्ति में लोड नहीं होने पर दिखाई देना और फिर ऑन लोडर सेट होने से पहले लोड करना।

हमने पाया कि आप जो चाहते हैं वह पाने का सबसे अच्छा तरीका है कि आप छवि के src को तब तक परिभाषित न करें जब तक कि आपने onloadईवेंट ट्रिगर सेट नहीं कर लिया है ।

हमने केवल हाल ही में IE8 का समर्थन करना बंद कर दिया है, इसलिए मैं IE9 से पहले के संस्करणों के लिए बात नहीं कर सकता, अन्यथा, साइट पर उपयोग किए गए अन्य सभी ब्राउज़रों में से - IE10 और 11 के साथ-साथ फ़ायरफ़ॉक्स, क्रोम, ओपेरा, सफारी और जो भी हो मोबाइल ब्राउज़र लोग उपयोग कर रहे थे - हैंडलर srcअसाइन करने से पहले सेटिंग करना onloadभी कोई समस्या नहीं थी।


0

क्या मैं पूरी तरह से शुद्ध सीएसएस समाधान सुझा सकता हूं?

बस एक Div है जिसे आप इमेज को दिखाना चाहते हैं। इमेज को बैकग्राउंड के रूप में सेट करें। फिर संपत्ति है background-size: coverया background-size: containआप कैसे चाहते हैं पर निर्भर करता है।

coverजब तक छोटे पक्ष बॉक्स को कवर नहीं करेंगे तब तक छवि को क्रॉप करेंगे। containdiv के अंदर पूरी छवि रखेंगे, जो आपको पक्षों पर रिक्त स्थान के साथ छोड़ देगा।

नीचे दिए गए स्निपेट की जांच करें।

div {
  height: 300px;
  width: 300px;
  border: 3px dashed grey;
  background-position: center;
  background-repeat: no-repeat;
}

.cover-image {
  background-size: cover;
}

.contain-image {
  background-size: contain;
}
<div class="cover-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)">
</div>
<br/>
<div class="contain-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)">
</div>


0

मुझे लगता है कि यह सरल समाधान मेरे लिए सबसे अच्छा काम करता है:

        function setEqualHeight(a, b) {
            if (!$(a).height()) {
                return window.setTimeout(function(){ setEqualHeight(a, b); }, 1000);
            }
            $(b).height($(a).height());
        }

        $(document).ready(function() {
            setEqualHeight('#image', '#description');
            $(window).resize(function(){setEqualHeight('#image', '#description')});
        });
    </script>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.