イベントをサポートする画像プリローダーのjavascript

私は画像プリローダースクリプトを見つけようとしています。

私はいくつか見つかりましたが、どれもプリロードが完了したときにトリガされるイベントをサポートしていません。

誰もがこれを行う任意のスクリプトやjQueryプラグインを知っていますか?

この質問がstackoverflowに適していることを願っています。そうでない場合は、すぐに削除してください。

6

4 答え

配列からイメージをプリロードし、最後のコールバックが終了したらコールバックを呼び出す関数は次のとおりです。

function preloadImages(srcs, imgs, callback) {
    var img;
    var remaining = srcs.length;
    for (var i = 0; i < srcs.length; i++) {
        img = new Image();
        img.onload = function() {
            --remaining;
            if (remaining <= 0) {
                callback();
            }
        };
        img.src = srcs[i];
        imgs.push(img);
    }
}

// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];

preloadImages(imageSrcs, images, myFunction);

そして今、非同期操作の約束を使用しているので、ここでは、約束を使用し、ES6標準の約束によって呼び出し元に通知する、上記のバージョンを示します。

function preloadImages(srcs) {
    function loadImage(src) {
        return new Promise(function(resolve, reject) {
            var img = new Image();
            img.onload = function() {
                resolve(img);
            };
            img.onerror = img.onabort = function() {
                reject(src);
            };
            img.src = src;
        });
    }
    var promises = [];
    for (var i = 0; i < srcs.length; i++) {
        promises.push(loadImage(srcs[i]));
    }
    return Promise.all(promises);
}

preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
   //all images are loaded now and in the array imgs
}, function(errImg) {
   //at least one image failed to load
});

そして、ここには2015年のjQueryの約束を使ったバージョンがあります:

function preloadImages(srcs) {
    function loadImage(src) {
        return new $.Deferred(function(def) {
            var img = new Image();
            img.onload = function() {
                def.resolve(img);
            };
            img.onerror = img.onabort = function() {
                def.reject(src);
            };
            img.src = src;
        }).promise();
    }
    var promises = [];
    for (var i = 0; i < srcs.length; i++) {
        promises.push(loadImage(srcs[i]));
    }
    return $.when.apply($, promises).then(function() {
       //return results as a simple array rather than as separate arguments
        return Array.prototype.slice.call(arguments);
    });
}

preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
   //all images are loaded now and in the array imgs
}, function(errImg) {
   //at least one image failed to load
});
27
追加された
うわー、ありがとう。これは素晴らしいものです! 100%!!
追加された 著者 SquareCat,
この関数を完全にするために、onerrorハンドラ、onabortハンドラ、タイムアウトを追加して、1つ以上のイメージに問題があり、正常に完了しない場合でもコールバックを呼び出すことができます。画像にエラーがない場合は正常に動作します。
追加された 著者 jfriend00,
標準のES6約束事とjQuery約束の両方を約束して使用する preloadImages()関数のバージョンを追加しました。
追加された 著者 jfriend00,
@AndrisZalitis - あなたは正しい。私はそれを修正した。
追加された 著者 jfriend00,
新しい追加に欠けているようです。img.src = src; after var img = new Image();
追加された 著者 Andris Zalitis,
はい、それはとてもいいです。私はそれを見せようとしていたが、私は不足していた。
追加された 著者 Simon,

より堅牢なソリューションを得るには、この PRELOADER 関数をいくつかのコールバック( jsFiddle )。

それを簡単に保つ:

この例では、 PRELOADER 内のコールバックをオーバーライドして、 Object リテラル PRELOADER_OBJECT 内にコールバックとイメージハッシュを渡します。

// preloder object stores image hash
// and event handler callbacks
var PRELOADER_OBJECT = {

    imgArray:"http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg".split(" "),

    progressCallback : function( percent )
    {
        $( '#preloader_progress' ).html( 'preload progress complete : ' + percent + '%' );
        console.log( 'preload progress complete : ', percent );
    },

    completeCallback : function( scope )
    {
       //hide preload indicator, do something when finished
        console.log( 'preload complete!' );
        $( '#preloader_modal' ).delay( 1000 ).animate( { opacity : 0 }, function( )
        {
            $( '.preload_class' ).each( function( index )
            {
                $( this ).delay( index * 100 ).animate( { opacity : 0 } );
            } );
        } );
    }

/*Localize params and create PRELOADER object. 
Needs to loadImages( ); iterate through hash and 
call onPreloadProgress( ) and onPreloadComplete( )
each time until finished. If you're still within
bounds of the image hash, call progressCallback( )
recursively. When finished, fire onCompleteCallback( )*/

var PRELOADER = function( object )
{
   //preloader modal overlay
    this.modal = undefined;

   //progress indicator container
    this.progressIndicator = undefined;

   //image preload progress
    this.progress = undefined;

   //progress callback
    this.progressCallback = undefined;

   //complete callback
    this.completeCallback = undefined;

   //hash to store key : value pairs for image paths
    this.imgArray = undefined; 

   //store images in preloadArray
    this.preloadArray = [];

   //initialize and localize our data
    this.initialize = function( )
    {
       //create preload indicator and overlay modal
        this.createPreloaderModal( );

       //image hash
        this.imgArray = object.imgArray;

       //progress callback event handler
        this.progressCallback = object.progressCallback;

       //complete callback event
        this.completeCallback = object.completeCallback;

       //load images
        this.loadImages( );
    };

    this.progressCallback = function( ) {};//function to override

    this.completeCallback = function( ) {};//function to override

   //load images into DOM and fire callbacks
    this.loadImages = function( )
    {
        var that = this;

       //iterate through hash and place images into DOM
        $.each( PRELOADER_OBJECT.imgArray, function( index, object )
        {
            this.image = $( "", { "src" : object, "class": "preload_class" } ).appendTo( 'body' );

           //mark progress and call progressCallback( ) event handler
            that.progress = Math.ceil( ( index/PRELOADER_OBJECT.imgArray.length ) * 100 );
            that.progressCallback( this.progress );

            that.preloadArray.push( this.image );
        } );

       //check for array bounds and call completeCallback( )
        if ( PRELOADER_OBJECT.imgArray.length )
        {
            this.progressCallback( 100 );
            this.completeCallback( this );
        }
    };

   //create modal to display preload data
    this.createPreloaderModal = function( )
    {
        this.modal = $( '<div/>', { 'id' : 'preloader_modal' } ).appendTo( 'body' );
        this.progressIndicator = $( '

', { 'id' : 'preloader_progress' } ).appendTo( this.modal ); }; }; // trigger event chain when DOM loads $( document ).ready( function( ) { //instantiate PRELOADER instance and pass //our JSON data model as a parameter var preloader = new PRELOADER( PRELOADER_OBJECT ); //initialize preloader preloader.initialize( ); } );

};

画像プリローダーが必要なサイトの負荷が大きい場合、モーダルテキストの表示を簡単に変更して、データ駆動のjQueryアニメーションをサポートすることができます。

2
追加された

プリロードには、新しいイメージ要素を作成し、それらがすべてロードされているかどうかを監視し、それらをDOM内の既存のものと置き換えるような余分な作業が必要です。しかし、DOM 要素でこれを置き換えることなく無限に何度も直接行うことができます。

Fetch APIを使用して画像にアクセスし、すべてが promise.all()内にダウンロードされるまで待ってから、そのコードの src window.requestAnimationFrame()を使用して、最も適切な時間に img 要素を追加します。

次の例では、 img 要素の src 属性を10回リフレッシュします。遅延ごとに、私はAPIから4つの画像を読み込むのにかかる時間を使用しています。ですから、すべての画像を読み込んだら、直ちに同じ refreshImagesNTimes 関数を再帰的に呼び出すことで新しいリクエストを行います。

もちろん、単純な setTimeout メカニズムを使用することで、一度に好きなだけ多くの画像ブロブを読み込んで、正確な時間間隔でグループに表示することができます。

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

function refreshImagesNTimes(nodeList,count = -1){
  var imgPromises = Array.from({length: nodeList.length})
                         .map(_ => fetch("https://unsplash.it/480/640/?random").then(res => res.blob()));
  Promise.all(imgPromises)
         .then(function(blobs){
                 window.requestAnimationFrame(_ => nodeList.forEach((img, i) => img.src = (window.URL || window.webkitURL).createObjectURL(blobs[i])));
                 --count && refreshImagesNTimes(nodeList, count);
               });
}

var images = document.querySelectorAll("#container img");
refreshImagesNTimes(images,10);
#container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
  align-items: center;
  margin: auto;
  width: 75vw;
  height: 56.25vw;
  background-color: #000;
  box-sizing: border-box;
}

img {
  width: 45%;
  height: 45%;
  background-color: thistle;
}
<div id="container">
  
  
  
  
</div>
</div> </div>

0
追加された

プリロードと読み込みは同じことです。イメージを挿入するか(新しいものを作成するか、既存のsrc属性を変更する)、 $( "element")やhide()などの要素を使って要素を隠すことができます。これを行う前に、次のようにloadイベントハンドラを添付します。

var images = ["src1", "src2", "src3", "src4"];
var len = images.length;

for(i=0; i
0
追加された
ありがとう、サイモン。私は表示されるべき国の一部がある連絡先マップのためにこれを設定しようとしています。これはそれぞれPNGであり、非常に巨大です。すべてを事前にロードしてから、コンテナにクラス名を追加して可視にします。それはほとんどすべてです。しかし、単一のイメージの読み込み時にトリガするためのコールバックを付けることは、私が探しているものではありません。
追加された 著者 SquareCat,
ありがとう、私は理解しますが、それは私が探しているものではありません。私は、バックグラウンドでそれらをロードし、次にイベントをトリガーする画像ソースの配列でフィードできるスクリプトを見つけようとしています。
追加された 著者 SquareCat,
「プリローディング」とはどういう意味ですか?ユーザーがそれを必要とする前にロードしたいと思っているので、見たいときには何千年もかかることはありません。上記のコードを使用してイメージを読み込みます。イメージが読み込まれると、そのイメージへの参照を保存して、ユーザーが参照する必要があるときに参照できるようにします。これにより効果的に画像がプリロードされます。
追加された 著者 Simon,
おそらく私の更新が役立つでしょう。そうでなければ、幸運。
追加された 著者 Simon,
イメージがロードされるたびに、var ++を実行し、var ==プリロードするイメージの数が "loaded loaded"ルーチンを実行する
追加された 著者 Thilo Savage,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript