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.