ホームページ  >  記事  >  ウェブフロントエンド  >  jQuery が画像のプリロード関数を実装する方法

jQuery が画像のプリロード関数を実装する方法

藏色散人
藏色散人オリジナル
2019-05-27 15:40:372951ブラウズ

最近、JavaScriptを使ってアニメーション機能を作りたいと思っています。アニメーションをスムーズにスムーズに再生するために、使用する画像素材をプリロードする必要があります。この機能を実装するプロセスを共有します

jQuery が画像のプリロード関数を実装する方法

単一イメージのプリロード

最も一般的な実装方法は次のとおりです

function preloadImg(url) {
    var img = new Image();
    img.src = url;
    if(img.complete) {
        //接下来可以使用图片了
        //do something here
    }
    else {
        img.onload = function() {
            //接下来可以使用图片了
            //do something here
        };
    }
}

まず、Image オブジェクトをインスタンス化します。値を img に設定し、img.src をパラメータ url で指定された画像アドレスに設定し、img の完全な属性を決定します。この画像のローカル キャッシュがある場合、値は true になります。この時点で、このイメージを直接操作します。ローカル キャッシュがない場合、値は false です。このとき、img の onload イベントを監視し、img に対する操作を onload コールバック関数に入れる必要があります。テスト後のこの解決策は、基本的に次のとおりです現在のすべてのブラウザと互換性

複数の画像のプリロード

アニメーションなどの関数には通常、多くの機能が含まれるため、多くのシナリオでは、単一の画像のプリロードではニーズを満たすことができません。次に、元の単一画像のプリロードに基づいて機能を改善します

function preloadImg(list) {
    var imgs = arguments[1] || [],    //用于存储预加载好的图片资源
        fn = arguments.cal    lee;
    if(list.length == 0) {
        return imgs;
    }
    var img = new Image();
    img.src = list[0];
    if(img.complete) {
        imgs.push(img);
        list.shift();
        fn(list, imgs);
    }
    else {
        img.onload = function() {
            imgs.push(img);
            list.shift();
            fn(list, imgs);
        };
    }
}
var list = [......],    //此处省略一万个字符
    imgs = preloadImg();

フレーム アニメーションでは、アニメーションの各フレームで使用される画像の順序を保証する必要があるため、このコードでは再帰を使用しますこのメソッドでは、前のピクチャがロードされた後に次のピクチャをロードします。ピクチャがロードされるたびに、ピクチャ リソースが imgs 配列に格納され、このピクチャのアドレスがアドレス配列リストから削除されます。リスト内で、再帰から抜け出して imgs 配列を返します。

アイデアは美しいですが、現実は残酷です。このコードには耐えられない問題が 2 つあります。

まず第一に、私はおそらくそうでしょう。ローカルにキャッシュされていない画像がある限り、imgs の保存操作は onload コールバック イベントに配置され、イベント監視も JavaScript の非同期操作の一種であるため、最後に返された imgs 配列は取得できません。 onload イベントのバインディング コールバック関数の後、preloadImg 関数は戻り値なしで終了します 外部 imgs 変数が受け取る値は未定義です すべての画像がローカル キャッシュを持つ場合にのみ、外部 imgs 変数はすべてのプリロードされた画像を正常に取得できます画像リソースの配列

1 つの画像をロードしてから次の画像をロードすると、画像のプリロード プロセス全体に比較的長い時間がかかり、ユーザー エクスペリエンスが低下し、元の非同期操作が特殊になります。この実装方法は、onload 非同期機能を完全に放棄するのと同じです。

複数画像のプリロード (改良版)

今回は、空の配列を直接配置します。がパラメータとして関数に渡され、すべての画像がこの配列に格納されます。以下は改良された関数コードです (jQuery を使用できると仮定しています)

function preloadImg(list,imgs) {
    var def = $.Deferred(),
        len = list.length;
    $(list).each(function(i,e) {
        var img = new Image();
        img.src = e;
        if(img.complete) {
            imgs[i] = img;
            len--;
            if(len == 0) {
                def.resolve();
            }
        }
        else {
            img.onload = (function(j) {
                return function() {
                    imgs[j] = img
                    len--;
                    if(len == 0) {
                        def.resolve();
                    }
                };
            })(i);
            img.onerror = function() {
                len--;
                console.log('fail to load image');
            };
        }
    });
    return def.promise();
}
var list = [......],    //此处省略一万个字符
    imgs = [];
$.when(preloadImg(list, imgs)).done(
    function() {
        //预加载结束
        //do something here
    }
);

onload コールバック関数を各 img に個別にバインドする場合クロージャを使用する目的は、現在のインクリメント変数 i を保存することです。これが行われない場合、ローカルにキャッシュされていないリスト アドレス内の画像が imgs

## の最後の要素に保存されることになります。 # 今回は画像がロードされるたびに、リスト配列から画像のアドレスを削除しないので、後でリスト配列のデータを使用する必要があるときに、正常に取得できます。このコードでは、jQuery の Deferred オブジェクトを導入しました。これにより、画像をプリロードするプロセス全体を簡単に把握できるようになります。

以上がjQuery が画像のプリロード関数を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。