jQuery로 이미지 사전로드


689

JavaScript로 이미지를 미리로드하는 빠르고 쉬운 방법을 찾고 있습니다. 중요한 경우 jQuery를 사용하고 있습니다.

나는 이것을 여기에서 보았다 ( http : //nettuts.com ... ) :

function complexLoad(config, fileNames) {
  for (var x = 0; x < fileNames.length; x++) {
    $("<img>").attr({
      id: fileNames[x],
      src: config.imgDir + fileNames[x] + config.imgFormat,
      title: "The " + fileNames[x] + " nebula"
    }).appendTo("#" + config.imgContainer).css({ display: "none" });
  }
};

그러나, 그것은 내가 원하는 것에 대해 약간 이상하게 보입니다!

나는 이것을 수행하는 jQuery 플러그인이 있다는 것을 알고 있지만 모두 조금 크다 (크기). 이미지를 빠르고 쉽고 빠르게 미리로드하는 방법 만 있으면됩니다.


10
$.each(arguments,function(){(new Image).src=this});
David Hellsing

답변:


969

빠른 쉬운 :

function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        $('<img/>')[0].src = this;
        // Alternatively you could use:
        // (new Image()).src = this;
    });
}

// Usage:

preload([
    'img/imageName.jpg',
    'img/anotherOne.jpg',
    'img/blahblahblah.jpg'
]);

또는 jQuery 플러그인을 원하는 경우 :

$.fn.preload = function() {
    this.each(function(){
        $('<img/>')[0].src = this;
    });
}

// Usage:

$(['img1.jpg','img2.jpg','img3.jpg']).preload();

25
브라우저가 이미지를 캐시하기 위해 이미지 요소를 DOM에 삽입 할 필요가 없습니까?
JoshNaro

8
$('<img />')메모리에 이미지 요소를 생성 한다고 생각 합니다 ( link 참조 ). '$('<img src="' + this + '" />')숨겨진 DIV 내에 요소를 실제로 만드는 것처럼 보입니다 . 더 복잡하기 때문입니다. 그러나 이것이 대부분의 브라우저에 필요하다고 생각하지 않습니다.
JoshNaro

104
jQuery 플러그인을 작성하는 이상한 방법입니다. 왜 안돼 $.preload(['img1.jpg', 'img2.jpg'])?
alex

12
$(window).load(function(){/*preload here*/});문서의 모든 이미지가 먼저로드되는 방식으로 먼저로드 해야하기 때문에 이것을 내부에 호출해야합니다 .
재스퍼 케니스

12
@RegionalC- 로드 이벤트가 설정되기 전에 이미지로드가 완료되는 경우를 대비하여 load설정하기 전에 이벤트를 설정하는 것이 조금 더 안전 할 수 src있습니까? $('<img/>').load(function() { /* it's loaded! */ }).attr('src', this);
스페어 바이트

102

다음은 실제로 이미지를 DOM에로드하고 기본적으로 숨기는 첫 번째 응답의 수정 된 버전입니다.

function preload(arrayOfImages) {
    $(arrayOfImages).each(function () {
        $('<img />').attr('src',this).appendTo('body').css('display','none');
    });
}

38
hide()보다 더 간결합니다 css('display', 'none').
alex

6
DOM에 삽입하면 어떤 이점이 있습니까?
alex

또한 DOM에 삽입 할 때의 이점을 알고 싶습니다.
jedmao

11
내 경험상 DOM에 이미지를 미리로드하면 브라우저가 존재를 인식하고 올바르게 캐시됩니다. 그렇지 않으면 이미지는 단일 페이지 앱에서만 작동하는 메모리에만 존재합니다.
Dennis Rongo

데니스 론고 Chrome에서 이미지를 DOM 고정 임의 다시로드에 추가합니다. 감사!
tmorell

52

JavaScript 이미지 객체를 사용하십시오 .

이 기능을 사용하면 모든 사진을로드 할 때 콜백을 트리거 할 수 있습니다. 그러나 하나 이상의 리소스가로드되지 않은 경우 콜백을 트리거하지 않습니다. onerror콜백 및 증분 loaded값 을 구현 하거나 오류를 처리하여 쉽게 해결할 수 있습니다 .

var preloadPictures = function(pictureUrls, callback) {
    var i,
        j,
        loaded = 0;

    for (i = 0, j = pictureUrls.length; i < j; i++) {
        (function (img, src) {
            img.onload = function () {                               
                if (++loaded == pictureUrls.length && callback) {
                    callback();
                }
            };

            // Use the following callback methods to debug
            // in case of an unexpected behavior.
            img.onerror = function () {};
            img.onabort = function () {};

            img.src = src;
        } (new Image(), pictureUrls[i]));
    }
};

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('a');
});

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('b');
});

4
옳은 일을하고 JavaScript Image 객체를 사용하십시오. 이 답변에서 사람들이 잘못한 것을 관찰 했 습니까?
alex

화려한 코드. onload이미지가 캐시 된 경우에도 이벤트 가 발생한다고 생각하는 것이 맞 습니까? ( img.onload먼저 선언 되었으므로 ). 이것이 내 테스트에서 보여준 것입니다.
Startec

3
@alex 잠재적으로 그렇습니다. 목표가 사전로드 (성능 순서를 제안하는) 경우 jQuery 종속 옵션 대신 원시 JS 옵션을 선호합니다.
Charlie Schliesser

이 솔루션을 좋아했지만 Firefox에서 작동하지 않는 것을 발견했습니다. 그것은 나입니까 아니면 다른 사람들이 같은 문제를 겪고 있습니까?
Gazillion

@Gazillion은 자세한 내용을 제공합니다. "작동하지 않음"을 어떻게 정의합니까? FF 버전은 무엇입니까?
Gajus

35

JP, 솔루션을 확인한 후에도 페이지로드와 함께 이동하기 전에 이미지를 미리로드하지 않는 Firefox에서 여전히 문제가 발생했습니다. sleep(5)서버 측 스크립트 에 일부 를 넣어서 이것을 발견했습니다 . 나는 이것을 해결하는 것처럼 당신을 기반으로 다음과 같은 솔루션을 구현했습니다.

기본적으로 jQuery 프리로드 플러그인에 콜백을 추가하여 모든 이미지가 올바르게로드 된 후 호출되도록했습니다.

// Helper function, used below.
// Usage: ['img1.jpg','img2.jpg'].remove('img1.jpg');
Array.prototype.remove = function(element) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == element) { this.splice(i,1); }
  }
};

// Usage: $(['img1.jpg','img2.jpg']).preloadImages(function(){ ... });
// Callback function gets called after all images are preloaded
$.fn.preloadImages = function(callback) {
  checklist = this.toArray();
  this.each(function() {
    $('<img>').attr({ src: this }).load(function() {
      checklist.remove($(this).attr('src'));
      if (checklist.length == 0) { callback(); }
    });
  });
};

관심이 없다면 내 맥락에서 다음과 같이 사용하고 있습니다.

$.post('/submit_stuff', { id: 123 }, function(response) {
  $([response.imgsrc1, response.imgsrc2]).preloadImages(function(){
    // Update page with response data
  });
});

바라건대 이것은 Google 에서이 페이지를 방문하는 사람이 Ajax 호출에서 이미지를 미리로드하는 솔루션을 찾는 데 도움이되기를 바랍니다.


2
Array.prototype 엉망에 관심이없는 사람들을 위해 대신 할 수 있습니다 : checklist = this.length그리고 onload 함수에서 : checklist--그렇다면 :if (checklist == 0) callback();
MiniGod

3
소유하고 있지 않은 객체에 새로운 메소드를 추가하거나 기존 메소드를 제거하는 것은 JavaScript에서 최악의 사례 중 하나입니다.
Rihards September

훌륭하고 빠르지 만,이 코드는 이미지 중 하나가 손상되거나로드 할 수없는 경우 콜백을 발생시키지 않습니다.
SammyK

.attr({ src: this }).load(function() {...})해야한다 .load(function() {...}).attr({ src: this })그렇지 않으면 당신은 캐싱 문제가있는 것입니다.
케빈 B

25

이 한 줄의 jQuery 코드는 DOM 요소 img를 표시하지 않고 작성하고로드합니다.

$('<img src="img/1.jpg"/>');

4
@huzzah-스프라이트 만 사용하는 것이 좋습니다. 적은 HTTP 요청. :)
Alex K

22
$.fn.preload = function (callback) {
  var length = this.length;
  var iterator = 0;

  return this.each(function () {
    var self = this;
    var tmp = new Image();

    if (callback) tmp.onload = function () {
      callback.call(self, 100 * ++iterator / length, iterator === length);
    };

    tmp.src = this.src;
  });
};

사용법은 매우 간단합니다.

$('img').preload(function(perc, done) {
  console.log(this, perc, done);
});

http://jsfiddle.net/yckart/ACbTK/


이것은 정말 좋은 답변입니다. 실제로 가장 많이 투표 된 답변이되어야합니다.
sleepycal

1
일부 설명 단어는 좋았을 것입니다.
robsch

좋은 대답이지만 lorempixel.com 대신 picsum.photos 를 사용하는 것이 좋습니다
Aleksandar

19

이것을 처리하는 작은 플러그인이 있습니다.

waitForImages 라고 img하며 CSS의 이미지를 참조하여 요소 또는 요소 를 처리 할 수 ​​있습니다 ( 예 :) div { background: url(img.png) }.

CSS에서 참조한 이미지를 포함하여 모든 이미지 를로드하려는 경우 다음 과 같이하십시오.

$('body').waitForImages({
    waitForAll: true,
    finished: function() {
       // All images have loaded.
    }  
});

이 플러그인으로 인해 아직 페이지에 나타나지 않은 이미지가로드되거나 이미로드 된 이미지에만 이벤트가 첨부됩니까?
Dave Cameron

@DaveCameron 이미지가 보이는지 여부를 존중하지 않습니다. 쉽게 선택하고 변경할 수 있습니다- :visible사용자 정의 선택기에 추가하십시오 .
alex

이 플러그인은 매우 흥미롭게 보입니다. 그러나 jquery 문서load 는 이미지에 적용될 때 "일관되게 작동하지 않거나 브라우저 간을 안정적으로 작동하지 않는다"고 강조합니다 . 플러그인은 어떻게 그 문제를 해결 했습니까?
EleventyOne

@EleventyOne 사용자 정의 선택기와 관련하여 소스를 확인하십시오.
alex

@alex이 플러그인은 css에 설정된 이미지를 요소의 : hover에 어떻게로드합니까? 그것은 나를 위해 작동하지 않습니다
Philipp Hofmann

13

CSS display:none;규칙을 사용하여 HTML 어딘가에 이미지를로드 한 다음 js 또는 jquery로 원할 때 이미지 를 표시 할 수 있습니다

js 또는 jquery 함수를 사용하지 않고 미리로드하는 것은 CSS 규칙입니다.

예 : HTML

<img src="someimg.png" class="hide" alt=""/>

CSS :

.hide{
display:none;
}

jQuery :

//if want to show img 
$('.hide').show();
//if want to hide
$('.hide').hide();

jquery / javascript로 이미지를 미리로드하는 것은 좋지 않습니다. 이미지를 페이지에로드하는 데 몇 밀리 초가 걸리고 스크립트를 파싱하고 실행하는 데 밀리 초가 있습니다 (특히 이미지가 큰 경우). 당신이 그것을 보여줄 때까지 이미지가 전혀 보이지 않고 실제로 미리로드됩니다!


2
이 접근법에 대한 자세한 정보는 여기에서 찾을 수 있습니다 : perishablepress.com/…
gdelfino

3
그러나이 기술에는 큰 단점이 있습니다. 모든 이미지가로드 될 때까지 페이지가 완전히로드되지는 않습니다. 미리로드 할 이미지 수와 크기에 따라 시간이 걸릴 수 있습니다. 더 나쁜 것은 <img> 태그가 높이와 너비를 지정하지 않으면 일부 페이지를 렌더링하기 전에 이미지를 가져올 때까지 일부 브라우저가 대기 할 수 있습니다.

당신은 어쨌든 IMG를로드해야 @ 알렉스, 당신은 HTML로를로드하고 또는 당신이없는 안정적인 솔루션을가는 더 빠른 속도를 얻으려면, 점멸 절반로드 이미지의 모든 종류의 피할 경우 자유롭게 선택할 수
itsme

또한 난 정말 자바 스크립트와 html 태그를 만들 생각은 모든 단지 내 2 센트에서 읽을 수
itsme은

1
매우 복잡한 프로젝트를위한 매우 빠른 솔루션이 필요했습니다.
Germstorm

13

이 jquery imageLoader 플러그인은 단지 1.39kb입니다.

용법:

$({}).imageLoader({
    images: [src1,src2,src3...],
    allcomplete:function(e,ui){
        //images are ready here
        //your code - site.fadeIn() or something like that
    }
});

이미지를 동기식으로 또는 비동기식으로로드할지 여부 및 각 개별 이미지에 대한 전체 이벤트와 같은 다른 옵션도 있습니다.


@AamirAfridi 왜 그렇습니까?
Ian

1
콜백이 시작될 때까지 문서가 이미 준비 되었기 때문에 @Ian. $ (document) .ready는 DOM이로드되었는지 확인하는 데 사용됩니다. 콜백에 관해서는 모든 이미지가로드됨을 의미하므로 yoru DOM 이로 드되어 콜백 내부에서 document.ready가 필요하지 않습니다.
Aamir Afridi

1
@AamirAfridi 콜백에서 문서가 준비되었다는 보장이 없습니다. 어디에서 추론하고 있습니까? 플러그인 페이지 allcomplete에는 DOM이 준비된 후 콜백이 실행 된다는 내용이 없습니다 . DOM이 준비된 후에 이미지로드가 완료 될 가능성은 매우 높지만 가정 할 이유는 없습니다. 콜백이 마술이라고 생각하고 DOM이 준비된 후에 실행되는 이유를 모르겠습니다 ... 어떻게 어디서 얻을 수 있는지 설명 할 수 있습니까? 이미지가 DOM을 의미하지 않는다로드해서 준비
이안

@AamirAfridi 그리고 플러그인에 대한 문서조차도 : NB to use this as an image preloader simply put your $(document).ready(function(){}); into your 'allcomplete' event : > simples!...이 답변이 보여주는 것을 직접 추천합니다.
Ian

5
@AamirAfridi이 상황에는 맞지 않습니다. 플러그인은 프리 로더입니다. 가능한 빨리 실행하고 싶습니다. 그리고 당신은 가능한 한 빨리 화재를 원하고 있다는 DOM에 의존하지 않는 일이 많이있다 다음 은 DOM이 준비가되었을 때, 뭔가를이.
Ian

9

jQuery에서 이미지를 미리로드하고 콜백 함수를 얻는 빠르고 플러그인없는 방법은 여러 img태그를 한 번 에 만들고 응답을 계산하는 것입니다.

function preload(files, cb) {
    var len = files.length;
    $(files.map(function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}

preload(["one.jpg", "two.png", "three.png"], function() {
    /* Code here is called once all files are loaded. */
});
    

IE7을 지원하려면 약간 덜 예쁜 버전을 사용해야합니다 (다른 브라우저에서도 작동 함).

function preload(files, cb) {
    var len = files.length;
    $($.map(files, function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}

7

감사합니다! JP의 답변에 약간의 리프를 추가하고 싶습니다. 이것이 누군가에게 도움이되는지 모르겠지만이 방법으로 이미지 배열을 만들 필요가 없으며 큰 이미지를 미리로드 할 수 있습니다 엄지 손가락의 이름을 올바르게 지정하십시오. html로 모든 페이지를 작성하는 사람이 있기 때문에 편리합니다. 이미지 배열을 만들 필요가 없으며 작업이 망가질 수있는 다른 단계가 필요하지 않습니다.

$("img").each(function(){
    var imgsrc = $(this).attr('src');
    if(imgsrc.match('_th.jpg') || imgsrc.match('_home.jpg')){
      imgsrc = thumbToLarge(imgsrc);
      (new Image()).src = imgsrc;   
    }
});

기본적으로 페이지의 각 이미지에 대해 각 이미지의 src를 잡고, 특정 기준과 일치하면 (엄지 손가락 또는 홈 페이지 이미지) 이름을 변경하고 (이미지 src의 기본 문자열 대체) 이미지를로드합니다 .

필자의 경우 페이지에는 image_th.jpg와 같은 이름의 엄지 이미지가 가득했고 해당하는 큰 이미지의 이름은 image_lg.jpg입니다. 엄지 손가락을 크게하면 _th.jpg가 _lg.jpg로 바뀌고 큰 이미지가 모두 미리로드됩니다.

이것이 누군가를 돕기를 바랍니다.


3
    jQuery.preloadImage=function(src,onSuccess,onError)
    {
        var img = new Image()
        img.src=src;
        var error=false;
        img.onerror=function(){
            error=true;
            if(onError)onError.call(img);
        }
        if(error==false)    
        setTimeout(function(){
            if(img.height>0&&img.width>0){ 
                if(onSuccess)onSuccess.call(img);
                return img;
            }   else {
                setTimeout(arguments.callee,5);
            }   
        },0);
        return img; 
    }

    jQuery.preloadImages=function(arrayOfImages){
        jQuery.each(arrayOfImages,function(){
            jQuery.preloadImage(this);
        })
    }
 // example   
    jQuery.preloadImage(
        'img/someimage.jpg',
        function(){
            /*complete
            this.width!=0 == true
            */
        },
        function(){
            /*error*/
        }
    )

7
스택 오버플로에 오신 것을 환영합니다! 코드 블록 만 게시하는 대신 이 코드로 인해 문제가 해결 된 이유 를 설명 하십시오 . 설명이 없으면 대답이 아닙니다.
Martijn Pieters

3

다음 코드를 사용합니다.

$("#myImage").attr("src","img/spinner.gif");

var img = new Image();
$(img).load(function() {
    $("#myImage").attr("src",img.src);
});
img.src = "http://example.com/imageToPreload.jpg";

먼저로드 이벤트에 바인딩 한 다음 src를 설정하십시오.
Kevin B

1

매니페스트 파일을 사용하여 웹 브라우저에 모든 관련 이미지를로드하고 캐시하도록 알려줍니다. Grunt 및 grunt-manifest를 사용하여 자동으로이를 수행하고 사전로드 스크립트, 캐시 무효화 기, CDN 등에 대해 다시 걱정하지 않아도됩니다.

https://github.com/gunta/grunt-manifest


0

이것은 IE9에서도 작동합니다.

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });

1
캐싱으로 인해 결국 실패합니다. src 속성을 설정하기 전에 항상로드 이벤트를 바인드하십시오.
Kevin B

0

Google Maps API 맞춤 오버레이로이 작업을 수행하고 싶었습니다. 샘플 코드는 JS를 사용하여 IMG 요소를 삽입하며 이미지가로드 될 때까지 이미지 자리 표시 자 상자가 표시됩니다. https://stackoverflow.com/a/10863680/2095698 에서 도움이되는 답변을 찾았습니다 .

$('<img src="'+ imgPaht +'">').load(function() {
$(this).width(some).height(some).appendTo('#some_target');
});

이전에 제안 된대로 이미지를 미리로드 한 다음 img URL이로드 된 후 핸들러를 사용하여 img 객체를 추가합니다. jQuery의 문서는 캐시 된 이미지 가이 이벤트 / 핸들러 코드와 잘 작동하지 않는다고 경고하지만 FireFox와 Chrome에서 나를 위해 일하고 있으며 IE에 대해 걱정할 필요가 없습니다.


알다시피 캐시 된 이미지에서는 제대로 작동하지 않습니다. 해결 방법은 먼저로드 이벤트를 바인드 한 다음 src 속성을 설정하는 것입니다.
케빈 B

-1
function preload(imgs) {
    $(imgs).each(function(index, value) {
        $('<img />').attr('src', value).appendTo('body').css('display', 'none');
    });
}

.attr('src',value) 아니 .attr('src',this)

그냥 지적하기 위해 :)


this전달되는 콜백 내의 범위 $.each는 반복되는 값에 할당됩니다.
Oybek

? $ ([ 'img1.jpg', 'img2.jpg', 'img3.jpg']). each (함수 (색인, 값) {console.log (값); // img1.jpg console.log (this) ; // String {0 = "i", 1 = "m", 2 = "g", 기타 ...} $ ( '<img />'). attr ( 'src', this) .appendTo ( ' body '). css ('display ','none ');});
Whisher

흠. 당신이 여기 있다고 생각합니다. 예를 들어 $("div").each(function(i, el){ console.log(el == this);});모든 trues 를 생성합니다 . 배열에 대한 반복은 다르게 동작하는 것 같습니다.
Oybek

-2

커피 스크립트의 5 줄

array = ['/img/movie1.png','/img/movie2.png','/img/movie3.png']

$(document).ready ->
  for index, image of array
    img[index] = new Image()
    img[index].src = image

2
OP의 질문을 해결하기 위해 솔루션의 작동 방식을 확장 할 수 있습니까? 다른 사람들이 쉽게 이해할 수 있도록 코드에 주석을 달겠습니까?
Ro Yo Mi

-4

약간의 액션 스크립트를 아는 사용자는 최소한의 노력으로 플래시 플레이어를 확인하고 플래시 프리 로더를 만들어 html5 / Javascript / Jquery로 내보낼 수도 있습니다. 플래시 플레이어가 감지되지 않는 경우 사용하려면 youtube 역할을 사용하여 html5 플레이어로 돌아가는 방법에 대한 예를 확인하십시오. 내가 아직 잊어 버린 경우 세부 정보가 없으므로 아직 시작하지 않았기 때문에 나중에 게시해야하며 standerd Jquery 코드를 시험해 볼 것입니다.


이것은 해결책이 아닙니다. 브라우저는 기본적으로 Flash Player를 지원하지 않습니다. 기본 브라우저 언어 인 JavaScript로 쉽게 달성 할 수 있습니다.
Usman Ahmed

나는 2012 년부터 플래시 증오를 기억합니다 ... 정상적이지 않았습니다 ... 내가 어디를 가도 플래시라는 단어를 사용할 때 공격을 받았습니다.
피터 Gruppelaar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.