Javascript / jQuery를 사용하여 이미지가로드되었는지 어떻게 확인할 수 있습니까?


85

사용자의 브라우저 창에 맞게 큰 이미지의 크기를 조정하기 위해 Javascript를 작성하고 있습니다. (불행히도 소스 이미지의 크기를 제어하지 않습니다.)

따라서 다음과 같은 내용이 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있으므로 이미지 태그에 직접 onLoad 이벤트를 정의했습니다. 기록을 위해 다음은 내가 사용한 코드입니다.

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

그런 다음 Javascript에서 :

//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 여부에 관계없이 Javascript를 사용한 이미지 스타일링 max-width및 설정에 문제가 max-height있습니까? 그런 다음 최대 너비 / 높이를 뷰포트 너비 / 높이의 크기로 설정하여 작성하는 데 필요한 모든 코드를 피할 수 있습니다.

@ jon.wd7 : 나는 그 플러그인에 익숙하지 않으며 '08 년에 돌아 오지 않았을 수 있습니다. max-width와 max-height의 경우 두 가지가 있습니다. 1) IE에서는 지원되지 않습니다 (IE 8에 대해서는 잘 모르겠습니다). 2) 뷰포트의 크기가 변경되면 (창 크기가 조정되는 등) 최대 너비 / 최대 높이를 변경하려면 자바 스크립트가 여전히 필요합니다 (픽셀 측정 값이 아닌 "100 %"를 사용하면 안 될 수도 있음).
— Kip

quirksmode.org에 따르면 IE7 및 IE8에서 확실히 지원됩니다. 그래서 나는 당신의 문제를 잘 모르겠습니다. 저는 개인적으로 이와 같은 작은 것에 대해 IE6를 지원하지 않습니다. 그래서 그들이 보게 될 것은 JS가 활성화되지 않은 사용자가 보게 될 것과 똑같은 것입니다. 물론 재설정 max-width하고 max-height크기를 조정 해야합니다 . 그러나 그것은 .resize()실제로 사용하는 한 줄짜리 작업 입니다.

3
완전한 속성은 이미지가로드되었는지 여부를 알 수 명령형 방법을 제공합니다.
— BorisOkunskiy

1
@Adrien, Mozilla는 이제 Andoid (알 수 없음)를 제외한 모든 주요 브라우저에서 지원하는대로 완전하게 표시 됩니다.
— Oliver Bock 2015

답변:


33

이벤트 리스너를 추가하거나 이미지가 onload를 통해 자체적으로 알리도록합니다. 그런 다음 거기에서 치수를 파악하십시오.

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

사양에 따르면 onload는 body 및 frameset 요소에 대한 이벤트 일뿐입니다. 즉, 이것이 IE에서 작동한다고 생각하지만 다른 브라우저에서도 작동하는지 또는 추측 할 수있는 것인지는 모르겠습니다. 몇 주 전에이 문제를 조사했습니다 ...
— Jason Bunting

IE6, IE7, FF3, Opera9, Safair (Windows 베타) 및 Chrome (Windows 베타)에서 테스트했습니다.
— Kip

9
혼란스러운 행동과 내용은 권장하지 않습니다. 이벤트는 HTML이 아닌 자바 스크립트를 사용하여 적용해야합니다.
— dionyziz

10
그의 논평은 우리가 2008 년에 갇혀 있지 않았기 때문에 관련이 있습니다. 사람들은 여전히 ​​이것을 읽고 있으며 심지어 08 년에 나쁜 습관으로 간주되지 않았더라도 사람들이 지금 그 좋은 습관을 생각하는 것을 원하지 않습니다.
— Spoeken 2013 년

3
document.querySelector ( "img"). addEventListener ( "load", function () {alert ( 'onload!');});
— Frank Schwieterman 2013

14

은 Using 데이터가 저장 JQuery와 당신은 '로드'상태를 정의 할 수 있습니다.

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

그런 다음 다른 곳에서 할 수 있습니다.

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

2
다른 라이브러리 (jquery는 $를 소유하지 않음)와의 더 나은 호환성 jQuery(this)을 $(this)위해 대신 사용하십시오 . 특히 html에 JavaScript가있는 경우 더욱 그렇습니다.
— John Magnolia

11

정답은 event.special.load 를 사용하는 것입니다.

이미지가 브라우저 캐시에서로드되는 경우로드 이벤트가 트리거되지 않을 수 있습니다. 이러한 가능성을 설명하기 위해 이미지가 준비되면 즉시 실행되는 특수로드 이벤트를 사용할 수 있습니다. event.special.load는 현재 플러그인으로 사용할 수 있습니다.

.load () 의 문서에 따라


2
나는 이것을 코딩하기 전에이 대답을 보니 기뻤습니다. 기본적으로 핸들러는 핸들러를 설정하기 전에 먼저 이미지가로드되었는지 확인해야합니다. 이미로드 된 경우 콜백을 즉시 실행하십시오. 그게 뭐죠 $.ready. 너비 만 확인하라고 제안하려고했는데 문제가있어서 그 솔루션이 정말 마음에 듭니다.
— Juan Mendes 2013 년

5

Allain이 말한대로하고 싶지만 가끔 이미지가 dom 준비 전에로드되므로로드 핸들러가 실행되지 않습니다. 가장 좋은 방법은 Allain이 말한대로 수행하는 것이지만로드 핸들러를 부착 한 후 javascript로 이미지의 src를 설정합니다. 이렇게하면 발사를 보장 할 수 있습니다.

접근성 측면에서 자바 스크립트가없는 사용자도 사이트를 사용할 수 있습니까? img 태그에 올바른 src를 지정하고 js를 실행하기 위해 dom ready handler를 첨부 할 수 있습니다. 이미지 src를 지우고 (페이지 깜박임을 방지하기 위해 css로 고정 된 높이와 높이를 제공) img로드 핸들러를 설정합니다. 그런 다음 src를 올바른 파일로 재설정하십시오. 이렇게하면 모든 기지를 다룰 수 있습니다. :)


이 사이트는 Javascript가없는 사람들에게도 여전히 작동하며 모든 이미지를 보려면 스크롤하기 만하면됩니다.
— Kip

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 {
      ... 
    }
});

경고 img.complete 항상 제대로 브라우저에 의해 설정되어 있기 때문에이 답변하는 것은, IE8에 심각한 루프가 발생할 낮출 수 있습니다. ie8을 지원해야하는 경우 플래그를 사용하여 이미지가로드되었음을 기억하십시오.


잡아. 이 답변은 img.complete가 브라우저에서 항상 올바르게 설정되지 않기 때문에 ie8 이하에서 심각한 루프를 유발할 수 있습니다. ie8을 지원해야하는 경우 플래그를 사용하여 이미지가로드되었음을 기억하십시오.
— commonpike 2014

2

다음과 같이 시도하십시오.

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

6
감사. 그러나이 문제가 발생하기 전에 이미지가 이미로드되었을 가능성이 있습니다.이 경우로드 이벤트가 시작되지 않습니다.
— Kip

이미지 태그 바로 뒤에이 이벤트를 설정하는 스크립트 태그는 어떻습니까? ready를 사용하는 이유는 전체 문서가로드되었는지 확인하는 것입니다.이 경우에는 불필요합니다.
— Jason Goemaat

2

요소의 이미지가로드되었는지 확인하는 브라우저 간 호환 방법을 제공하는 "imagesLoaded"라는 jQuery 플러그인이 있습니다.

대지: https://github.com/desandro/imagesloaded/

내부에 많은 이미지가있는 컨테이너의 사용법 :

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

플러그인은 훌륭합니다.

  1. 내부에 많은 이미지가있는 컨테이너를 확인하는 작업
  2. 이미지가로드되었는지 확인하기 위해 작동합니다.

로드 된 img를 확인하기 위해 약간 무거운 5KB가 축소 된 것 같습니다. 사용 가능한 더 쉬운 가벼운 방법
— 이어야

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 Object 를 사용하여 이미지를로드하는 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

흥미로운 아이디어. 이미지가 언제 끝났는지 알기 쉽습니다. 그러나 이미지를로드 할 수 없다면 어떨까요? 이미지로드가 실패했는지 알 수있는 방법을 찾고있었습니다. 그리고 당신은 타임 아웃에 대한 아이디어를주었습니다. +1
— 오크

1
@oak 시간 제한은 대체 일 뿐이어야합니다. 대부분의 브라우저 error는에서 처리 하는 이벤트를 발생시켜야합니다 .error(function(e) { defer.rejectWith($img); }). jsFiddle을 보면 http://www.google.com/abc.png not found텍스트가 결과 창에 즉시 표시되는 것을 볼 수 있습니다 (오류 이벤트가 시작 되었기 때문에 시간 초과를 기다리지 않음)
— roberkules 2014

jquery가 .error를 발생 시키려면 두 가지가 1. 핸들이지만 오류가 발생하기 전에 설정되어야합니다. 2.에는 .error 핸들에만 HTTP 프로토콜이 아닌 파일 : // 당신이 .. 오류가 실 거예요 그래서
— 오크

내 코드 예제에서 성공 / 오류 핸들러는 정확히 그 이유 때문에 src 속성을 할당하기 전에 설정됩니다. file://제한 사항 에 대해 -파일 프로토콜을 사용하여 이미지를 연결할 필요가 없었으며 그다지 필요하지 않다고 생각합니다.
— roberkules 2014

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

이 솔루션은 이미지에 여백이나 패딩이 없어야하고 빈 문자열의 대체 텍스트가 제공되어야한다는 것을 발견했습니다. 하지만 대부분의 경우 의도 한대로 작동합니다. 언로드 된 이미지의 크기가 0보다 큰 경우에만 실패합니다.
— 랄프 Ritoch

1

나는 이것이 나를 위해 일했다는 것을 알았다.

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

받아 들여진 대답에 대해 논평 한 Frank Schwieterman에게 신용이 전적으로 간다. 여기에 넣어야했는데 너무 귀중한 데 ...


0

많은 이미지를로드 한 페이지를 개발 한 후 이미지가로드 된 후에 만 ​​다른 기능을 수행했습니다. 많은 트래픽이 발생하는 바쁜 사이트였습니다. 다음과 같은 간단한 스크립트가 거의 모든 브라우저에서 작동하는 것 같습니다.

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

그러나 이것은 IE9의 잠재적 인 문제입니다!

문제를보고 한 유일한 브라우저는 IE9입니다. 우리는 놀라지 않습니까? 문제를 해결하는 가장 좋은 방법은 다음과 같이 onload 함수가 정의 될 때까지 이미지에 src를 할당하지 않는 것 같습니다.

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

IE 9는 때때로 onload 어떤 이유로 든 이벤트를 . 이 페이지의 다른 솔루션 (예 : Evan Carroll의 솔루션)은 여전히 ​​작동하지 않았습니다. 논리적으로로드 상태가 이미 성공했는지 확인하고 함수를 트리거 한 다음 그렇지 않은 경우 onload 핸들러를 설정했지만 그렇게해도 이미지가 두 줄의 js 사이에로드 될 수 있음을 테스트에서 입증했습니다. 첫 번째 줄에로드되지 않은 것으로 나타난 다음 onload 핸들러가 설정되기 전에로드됩니다.

원하는 것을 얻는 가장 좋은 방법은 onload이벤트 트리거를 설정할 때까지 이미지의 src를 정의하지 않는 것 입니다.

우리는 최근에야 IE8 지원을 중단했기 때문에 IE9 이전 버전에 대해서는 말할 수 없습니다. 그렇지 않으면 사이트에서 사용 된 다른 모든 브라우저 (IE10 및 11, Firefox, Chrome, Opera, Safari 등)에 대해 말할 수 없습니다. 사람들이 사용하는 모바일 브라우저- 핸들러 src를 할당하기 전에 설정하는 onload것은 문제가되지 않았습니다.


0

순수한 CSS 솔루션을 모두 제안해도 될까요?

이미지를 표시하려는 Div가 있습니다. 이미지를 배경으로 설정하십시오. 그런 다음 재산을 background-size: cover갖거나 background-size: contain원하는 방식에 따라.

cover 작은면이 상자를 덮을 때까지 이미지를 자릅니다. contain전체 이미지를 div 내부에 유지하여 측면에 공백을 남깁니다.

아래 스 니펫을 확인하세요.

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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.