ホームページ  >  記事  >  ウェブフロントエンド  >  画像のプリロード中に不明な _javascript スキルを非表示にする

画像のプリロード中に不明な _javascript スキルを非表示にする

WBOY
WBOYオリジナル
2016-05-16 17:46:14873ブラウズ

マンチェスター・ユナイテッドとマンチェスター・シティの地元ダービーを観た後、待ちに待った全国ダービーを観るまでにはまだ2時間もの長い時間がある。私はとても退屈で何もすることがなかったので、たむろするためにフォーラムに来ました。画像のプリロードに関するブログ投稿を見ました。コードは次のとおりです:

コードをコピーします コードは次のとおりです:

function loadImage(url, callback) {
var img = new Image() //画像を事前にダウンロードするための Image オブジェクトを作成します
img.src = url
if; (img.complete) { // 画像がブラウザのキャッシュに既に存在する場合は、コールバック関数を直接呼び出します
callback(img)
return; // onload イベントを処理せずに直接返します
}
img.onload = function () { //画像のダウンロード時にコールバック関数を非同期的に呼び出します。
callback(img);
};
};

ネットで関連記事を探してみると、大体こんな感じです。
このメソッドの機能は問題ありませんが、いくつかの隠れた危険性があります。
1 イメージの onload イベント ハンドラーとして一時的な匿名関数を作成し、クロージャを形成します。
IE でのメモリ リーク パターンに関する記事を皆さんもご覧になったことがあると思います。パターンの 1 つは循環参照であり、クロージャには (スコープ チェーンの実装に応じて) 外部の動作環境を保存する機能があります。 onload 関数は img への参照も保存しますが、これにより循環参照が形成され、メモリ リークが発生します。 (このモードのメモリ リークは、IE6 の以前のバージョンにのみ存在します。パッチが適用された IE6 以降のバージョンの IE では、循環参照によって引き起こされるメモリ リークの問題が解決されています。)

2 は静的画像の読み込みのみを考慮し、onload を複数回トリガーする可能性がある GIF などの動的画像を無視します。
上記の 2 つの問題を解決するのは非常に簡単です。実際、コードは次のとおりです。
コードをコピーします。 コードは次のとおりです。

img.onload = function () {
//画像のダウンロード時にコールバック関数を非同期的に呼び出します。
img.onload = null;
callback(img);

これにより、メモリリークの問題を解決できるだけでなく、動的画像の複数のトリガーの問題も回避できます。イベント。
一部の関連ブログ投稿では、img.onload を null に設定する必要があることに気づいた人もいますが、ほとんどの記事ではコールバックの実行後に img.onload を null に設定することで問題を解決できます。循環参照の問題はありますが、動的なピクチャの場合、コールバックの実行に時間がかかる場合、複数回トリガーされる危険性が潜んでいます。
上記の修正により隠れた危険性は排除されましたが、このコードにはまだ最適化の余地があります:
コードをコピー コード以下のように:

if (img.complete) {
// 画像がブラウザーのキャッシュに既に存在する場合は、コールバック関数
callback(img); を直接呼び出します。 return; // onload イベントを処理せずに直接戻ります
}

このコードについては、関連するブログ投稿の説明を読んでください。理由は次のとおりです。複数のブラウザのバージョンを確認したところ、IE と Opera では、画像が一度ロードされた後、その画像に対する別のリクエストがあった場合、ブラウザはすでに画像をキャッシュしているため、新しいリクエストは開始されず、直接ロードされることがわかりました。キャッシュから来てください。 Firefox と Safari では、これら 2 つの読み込みメソッドをユーザーに対して透過的にしようとします。これにより、画像の onload イベントも発生しますが、IE と Opera はこのアイデンティティを無視し、画像の onload イベントを発生させません。上記のコードは、その中では効果を達成できません。

確かに、IE と Opera では、キャッシュされた画像の初期状態は、Firefox、Safari、Chrome とは異なります (興味がある場合は、別のブラウザでテストして、以前の img の状態を img に与えることができます) src にはキャッシュされた画像の URL が割り当てられますが、onload イベントのトリガーはブラウザーに関係なく一貫しています。この問題の根本原因は、img の src 値と onload イベントのバインディングの順序が間違っていることです (IE と Opera では、イメージがキャッシュされ、onload イベントが逃しました)。最初に onload イベントをバインドしてから、src に値を割り当てる必要があります。コードは次のとおりです。


コードをコピーします
function loadImage(url, callback) {
var img = new Image() //画像を事前ダウンロードするための Image オブジェクトを作成します
img.onload = function(){
img .onload = null;
callback(img);
}
img.src = url;
このようにして、メモリリークと動的イメージロードの問題が解決され、コールバック呼び出しを実装するための統一された方法も追加されました。

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