이미지로드시 jQuery 콜백 (이미지가 캐시 된 경우에도)


291

나하고 싶어:

$("img").bind('load', function() {
  // do stuff
});

그러나 이미지가 캐시에서로드 될 때로드 이벤트가 발생하지 않습니다. jQuery 문서 는 이 문제를 해결하기 위해 플러그인 을 제안 하지만 작동하지 않습니다.


12
당신의 질문이 바뀌었기 때문에. 깨진 플러그인은 작은 작동 플러그인 jQuery.imagesLoaded 를 사용하여 요지로 이동 한 다음 나중에 리포지토리로 이동했습니다 . 그들은 모든 작은 브라우저 문제를 해결합니다 .
Lode

위에서 언급 한 JQuery 라이브러리는 저에게 잘 작동했습니다. 감사!
plang

플러그인 주셔서 감사합니다, 잘 작동했습니다.
onimojo

답변:


572

src이 이미 설정되어 있으면 이벤트 처리기가 바인딩되기 전에 캐시 된 사례에서 이벤트가 시작됩니다. 이 문제를 해결하려면 다음과 같이 이벤트 기반 점검 및 트리거를 반복 .complete하십시오.

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) {
      $(this).load(); // For jQuery < 3.0 
      // $(this).trigger('load'); // For jQuery >= 3.0 
  }
});

에서 변경 참고 .bind().one()이벤트 핸들러가 두 번 실행하지 않도록합니다.


8
귀하의 솔루션은 완벽하게 작동했지만 이미지 내용이로드 된 후 또는이 전에이 코드 "if (this.complete)"가 실행될 때 무언가를 이해하고 싶습니다. 이 .each에서 알 수 있듯이 모든 $ ( "img")에서 반복하고 이미지 내용이 비어 있고로드가 발생하지 않을 수 있습니다. 흠, 내가 잃어버린 것이 있다고 생각합니다. 더 잘 이해하기 위해 설명 할 수 있다면 좋을 것입니다. 감사.
Amr Elgarhy

33
당신의 대답이 바뀌었기 때문에. 지금이 플러그인 작은 작업 jQuery.imagesLoaded은 . 그들은 모든 작은 브라우저 문제를 해결합니다 .
Lode

3
setTimeout(function(){//do stuff},0)'load'함수 내에를 추가하고 싶습니다 . 0 은 브라우저 시스템 (DOM)에 모든 추가 정보가 올바르게 업데이트되도록 추가로 한 번의 틱을 제공합니다.
dsdsdsdsd 10

14
@Lode-그것은 어떤 규모로든 작지 않은 거대한 플러그인입니다!
vsync

5
JQuery 3 메소드 .load()는 이벤트를 트리거하지 않고 필요한 인수가 1 개 .trigger("load")
이므로

48

DOM이 아닌 이미지 객체로 다시로드 할 것을 제안 할 수 있습니까? 캐시 된 경우 시간이 전혀 걸리지 않으며 온로드는 계속 실행됩니다. 캐시되지 않은 경우 이미지가로드 될 때 온로드를 발생 시키며, 이는 이미지의 DOM 버전이로드를 완료하는 시간과 같아야합니다.

자바 스크립트 :

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.src = $('#img').attr('src') ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;
}) ;

업데이트 됨 (여러 이미지를 처리하고 올바르게 정렬 된 온로드 첨부 파일로) :

$(document).ready(function() {
    var imageLoaded = function() {
        // Run onload code.
    }
    $('#img').each(function() {
        var tmpImg = new Image() ;
        tmpImg.onload = imageLoaded ;
        tmpImg.src = $(this).attr('src') ;
    }) ;
}) ;

1
load처리기 추가 하기 전에 처리기 를 연결해야합니다 . 또한 작동하지 않지만 하나의 이미지에서는 OPs 코드가 많은 경우 작동합니다.
Nick Craver

감사합니다.이 두 가지 문제를 해결하기 위해 업데이트 된 버전을 추가했습니다.
거스

#img는 요소 선택기가 아닌 ID입니다. :) 또한 this.src작동합니다. 필요하지 않은 곳에서는 jQuery를 사용할 필요가 없습니다.
Nick Craver

$ ( 'img')이어야합니다. 하지만 해결책은 2k15에서 GR8이기도하다
Dimag Kharab

또한 여러 이미지 사례의 경우에서 각 이미지의 DOM 요소에 대해 작업 imageLoaded하려면tmp.onload = imageLoaded.bind(this)
blisstdev

38

내 간단한 솔루션, 외부 플러그인이 필요하지 않으며 일반적인 경우 충분합니다.

/**
 * Trigger a callback when the selected images are loaded:
 * @param {String} selector
 * @param {Function} callback
  */
var onImgLoad = function(selector, callback){
    $(selector).each(function(){
        if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
            callback.apply(this);
        }
        else {
            $(this).on('load', function(){
                callback.apply(this);
            });
        }
    });
};

다음과 같이 사용하십시오.

onImgLoad('img', function(){
    // do stuff
});

예를 들어,로드시 이미지를 페이드하려면 다음을 수행하십시오.

$('img').hide();
onImgLoad('img', function(){
    $(this).fadeIn(700);
});

또는 jquery 플러그인과 같은 접근 방식을 선호하는 경우 :

/**
 * Trigger a callback when 'this' image is loaded:
 * @param {Function} callback
 */
(function($){
    $.fn.imgLoad = function(callback) {
        return this.each(function() {
            if (callback) {
                if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
                    callback.apply(this);
                }
                else {
                    $(this).on('load', function(){
                        callback.apply(this);
                    });
                }
            }
        });
    };
})(jQuery);

그리고 이런 식으로 사용하십시오 :

$('img').imgLoad(function(){
    // do stuff
});

예를 들면 다음과 같습니다.

$('img').hide().imgLoad(function(){
    $(this).fadeIn(700);
});

urm .. 그리고 내 이미지의 크기가 CSS로 설정되어 있으면 어떻게됩니까?
Simon_Weaver

Set width, max-heightleave height:auto, 이미지를 늘려야하는 경우에만 너비와 높이를 모두 설정해야하는 경우가 종종 있습니다. 보다 강력한 솔루션을 위해 ImagesLoaded
guari

1
그렇습니다. jsdoc가
잘못

1
$ .fn.imgLoad가 포함 된이 솔루션은 여러 브라우저에서 작동합니다. IE 10- *의 경우 && / * : this.naturalHeight> 0이 줄은 img를 차단할 수 있지만 높이가 있기 때문에 CSS 스타일을 고려하지 않습니다. IE10에서 작업
Patryk Padus

1
이것은 (작은) 경쟁 조건이 있습니다. 이미지는 다른 스레드에서 스크립트로로드 될 수 있으므로 완료 확인과 onload 이벤트 연결 사이에로드 될 수 있으며,이 경우 아무 일도 발생하지 않습니다. 일반적으로 JS는 렌더링과 동기화되므로 경쟁 조건에 대해 걱정할 필요가 없지만 예외입니다. html.spec.whatwg.org/multipage/…
Mog0

23

실제로 jQuery와 함께해야합니까? onload이벤트를 이미지에 직접 첨부 할 수도 있습니다.

<img src="/path/to/image.jpg" onload="doStuff(this);" />

캐시에서 이미지가로드 될 때마다 실행됩니다.


5
그것은 인라인 자바 스크립트없이 깨끗합니다
개암

1
안녕하세요, Bjorn, onload이미지가 캐시에서 두 번째로로드 될 때 핸들러가 실행됩니까?
SexyBeast

1
@Cupidvogel 아니오 그렇지 않습니다.
광고

3
야, 너는 내 목숨을 구했다. 나는 적어도 12 가지의 다른 해결책을 시도해 보았고, 당신의 유일한 해결책은 실제로 효과가 있었다. 답변을 10 번 더 투표하기 위해 10 개의 계정을 더 만드는 것에 대해 진지하게 생각하고 있습니다. 진심으로 감사합니다!
Carlo

1
나는 인라인 JS에 대한 사람들의 혐오감을 결코 이해하지 못했습니다. 이미지로드는 나머지 페이지로드 프로세스와 별도로 그리고 순서가 맞지 않습니다. 따라서 이는 이미지로드 완료에 대한 즉각적인 피드백을 얻는 유일한 솔루션입니다. 그러나 누군가 jQuery 가로 드 될 때까지 기다려야하고 나중에 발생하는 경우 여기에서 간단한 솔루션을 사용하지 말고 다른 솔루션 중 하나를 사용해야합니다 (Piotr은 의사에 의존하지 않기 때문에 아마도 가장 좋은 옵션 일 것입니다. 해킹하지만 guari의 height () 확인도 중요 할 수 있습니다). 처리 대기열도 유용 할 수 있습니다.
CubicleSoft

16

로드 오류를 지원하여이 코드를 사용할 수도 있습니다.

$("img").on('load', function() {
  // do stuff on success
})
.on('error', function() {
  // do stuff on smth wrong (error 404, etc.)
})
.each(function() {
    if(this.complete) {
      $(this).load();
    } else if(this.error) {
      $(this).error();
    }
});

1
이것은 나를 위해 가장 잘 작동했습니다. 열쇠는 load핸들러를 먼저 설정 한 다음 나중에 each함수 에서 호출하는 것입니다.
GreenRaccoon23

아래 코드를 사용하여 이미지 설정 ''var img = new Image (); img.src = sosImgURL; $ (img) .on ( "load", function () { ''
imdadhusen

13

방금이 문제가 있었고 캐시를 죽이거나 플러그인을 다운로드하지 않는 솔루션을 어디서나 검색했습니다.

나는이 스레드를 즉시 보지 못했기 때문에 대신 재미있는 수정이며 여기에 게시 할 가치가있는 다른 것을 발견했습니다.

$('.image').load(function(){
    // stuff
}).attr('src', 'new_src');

나는 실제로 여기에 의견 에서이 아이디어를 얻었다 : http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/

나는 그것이 왜 작동하는지 모르겠지만 IE7에서 이것을 테스트했으며 그것이 작동하기 전에 어디에서 깨졌습니까?

도움이 되길 바랍니다.

편집하다

허용 된 답변은 실제로 다음과 같은 이유를 설명합니다.

src가 이미 설정되어 있으면 이벤트 핸들러를 바인드하기 전에 이벤트가 캐시에서 발생합니다.


4
나는 이것이 많은 브라우저에서 테스트되었으며 어디에서나 실패한 것을 발견하지 못했습니다. $image.load(function(){ something(); }).attr('src', $image.attr('src'));원래 소스를 재설정하는 데 사용 했습니다.
Maurice

나는이 방법은 / 602.1 사파리 / 601.1와 사파리에 대한 최소한 iOS에서 작동하지 않는 것으로 나타났습니다
cronfy

왜 어떤 브라우저에 있는지 알아내는 것이 좋을까요?
Sammaye

5

jQuery를 사용하여 이미지의 src로 새 이미지를 생성하고 그에 직접로드 메소드를 지정하면 jQuery가 새 이미지 생성을 마치면로드 메소드가 성공적으로 호출됩니다. 이것은 IE 8, 9 및 10에서 나를 위해 일하고 있습니다.

$('<img />', {
    "src": $("#img").attr("src")
}).load(function(){
    // Do something
});

__rjs.erb 템플릿을 사용하여 원격 요청으로 Ruby on Rails를 사용하는 사람들에게는 이것이 내가 찾은 유일한 솔루션입니다. js.erb에서 부분을 사용하기 때문에 바인딩 해제 ($ ( "# img".on ( "load") ...)가 풀리고 이미지의 경우 "on"메소드를 위임 할 수 없습니다 : $ ( "body"). on ( "load", "# img", function () ...
Albert Català

5

내가 찾은 해결책 https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (이 코드는 주석에서 직접 가져 왔습니다)

var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;

이것이 바로 내가 찾던 것입니다. 서버에서 단일 이미지가 나에게 온다. 나는 그것을 미리로드하고 봉사하고 싶었다. 많은 답변처럼 모든 이미지를 선택하지는 않습니다. 좋아요
Kai Qing

4

GUS의 예에 대한 수정 :

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;

tmpImg.src = $('#img').attr('src');
})

온로드 전후에 소스를 설정하십시오.


@Gus의 답변과 같이, 이것은 여러 이미지에서 작동하지 않습니다 ... 처리기를 src연결하기 전에 를 설정하지 않아도 onload나중에는 충분합니다.
Nick Craver

3

img oject가 정의 된 후 별도의 행에 src 인수를 다시 추가하십시오. 이것은 IE를 속여 이벤트를 트리거하도록 속입니다. 추악하지만 지금까지 내가 찾은 가장 간단한 해결 방법입니다.

jQuery('<img/>', {
    src: url,
    id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE

1

당신이 이것을 원한다면 나는 당신에게 작은 팁을 줄 수 있습니다 :

<div style="position:relative;width:100px;height:100px">
     <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
     <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>

브라우저가 사진을 캐시 할 때 그렇게하면 항상 img가 표시되지만 실제 그림 아래에 img를로드하는 데 아무런 문제가 없습니다.


1

e.target.width가 정의되지 않은 IE 에서이 문제가 발생했습니다. 로드 이벤트가 발생하지만 IE에서 이미지의 크기를 가져올 수 없습니다 (chrome + FF 작동).

당신 밝혀 찾는다 필요 e.currentTarget.naturalWidth & e.currentTarget.naturalHeight .

다시 한 번, IE는 자신의 (더 복잡한) 방식으로 작업을 수행합니다.


0

JAIL 플러그인을 사용하여 이미지로드 지연 (페이지 성능 향상) 및 콜백 을 매개 변수로 전달할 수있는 문제점을 해결할 수 있습니다.

$('img').asynchImageLoader({callback : function(){...}});

HTML은 다음과 같아야합니다

<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />

0

순수한 CSS 솔루션을 원한다면이 트릭이 잘 작동합니다. 변환 객체를 사용하십시오. 이미지가 캐시되거나 캐시되지 않은 경우에도 작동합니다.

CSS :

.main_container{
    position: relative;
    width: 500px;
    height: 300px;
    background-color: #cccccc;
}

.center_horizontally{
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: green;
  left: 50%;
  top: 0;
  transform: translate(-50%,0);
}

.center_vertically{
  position: absolute;
  top: 50%;
  left: 0;
  width: 100px;
  height: 100px;
  background-color: blue;
  transform: translate(0,-50%);
}

.center{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  height: 100px;
  background-color: red;
  transform: translate(-50%,-50%);
}

HTML :

<div class="main_container">
  <div class="center_horizontally"></div>
  <div class="center_vertically"></div>
  <div class="center"></div>
  </div>
</div

코드 펜 예

Codepen LESS 예


이것이 이미지 로딩에서 어떻게 작동하는지 예를 들어 주시겠습니까?
Hastig Zusammenstellen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.