ユーザーがスクロールすると画像が動的にロードされる非常に長いページがあります。
ただし、ユーザーがページの特定の部分からすばやくスクロールした場合、ページの現在表示されていない部分で画像の読み込みを続行したくありません。
画像の読み込みとは別に、ページ上で同時に発生する他の多くのリクエストがあります。そのため、スクロールイベントで発生する鈍いwindow.stop()は受け入れられません。
表示されなくなった画像のimg src属性を削除およびクリアしようとしましたが、リクエストはすでに開始されているため、画像はロードされ続けます。
ユーザーがページのその部分を短くスクロールすると、画像srcが塗りつぶされたことを思い出してください。ただし、一度過ぎてしまうと、window.stop()を使用しないと、そのイメージの読み込みを停止できませんでした。 srcのクリアが機能しませんでした。 (クローム&FF)
私が見つけた同様の投稿は近づいていますが、この問題を解決していないようです:
nrabinowitz で述べられているように、あなたがやろうとしているのは間違ったアプローチです。画像の読み込みプロセスを単に「キャンセル」することはできません(src
属性を空の文字列に設定すると、 良いアイデアではありません )。実際、たとえできたとしても、サーバーはキャンセルされたデータを継続的に送信し、負荷率を上げて速度を落とすため、事態が悪化するだけです。また、これを考慮してください:
多くの場合、コンピューターの問題は単に設計上の問題です。
**[〜#〜] edit [〜#〜]**
ここにアイデアがあります:
ページには、期待される画像サイズの幅と高さでDIV
コンテナが表示されます(スタイル設定にCSSを使用)。各DIV
の中に、リンクを追加します。例えば :
<div class="img-wrapper thumbnail">
<a href="http://www.domain.com/path/to/image">Loading...</a>
</div>
このJavascriptを追加します(テストされていない、アイデアは自己記述的です)
$(function() {
var imgStack;
var loadTimeout;
$(window).scroll(function() {
imgStack = null;
if (loadTimeout) clearTimeout(loadTimeout);
loadTimeout = setTimeout(function() {
// get all links visible in the view port
// should be an array or jQuery object
imgStack = ...
loadNextImage();
}, 200); // 200 ms delay
});
function loadNextImage() {
if (imgStack && imgStack.length) {
var nextLink = $(imgStack.pop()); // get next image element
$('<img />').attr('src', nextLink.attr('href'))
.appendTo(nextLink.parent())
.load(function() {
loadNextImage();
});
// remove link from container (so we don't precess it twice)
nextLink.remove();
}
};
});
さて、私の考え:
1)画像のAJAXリクエストを開始し、成功した場合、画像はブラウザキャッシュに移動し、「src」属性を設定すると、画像はキャッシュから表示されます
2)XHRを中止できます
巨大なイメージのダウンロードを高速でエミュレートする小さなサーバーを作成しました(実際には20秒待機してからイメージを返します)。その後、私はこれを私のHTMLに持っています:
<!DOCTYPE html>
<html>
<head>
<style>
img {
width: 469px;
height: 428px;
background-color: #CCC;
border: 1px solid #999;
}
</style>
</head>
<body>
<img data-src="./img" src="" />
<br />
<a id="cancel" href="javascript:void(0)">CANCEL</a>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>
$(function () {
var xhr, img = $('img'), src = img.data('src');
xhr = $.ajax(src, {
success: function (data) { img.attr('src', src) }
});
$('#cancel').click(function (){
xhr.abort();
})
});
</script>
</body>
</html>
Ajax呼び出しを使用して画像を読み込むことができます。スクロールアウトを使用する場合は、呼び出しを中止できます。
jQuery擬似コードでは、次のようなものになります(構文の誤りを許してください。これは単なる例です)。
1)ロードする画像にタグを付けます
$(".image").each( function(){
if ( is_in_visible_area(this) ) { // check [1] for example
$(this).addClass("load_me");
} else {
$(this).addClass("dont_load");
}
});
2)画像を読み込む
ajax_requests = {};
$(".image.load_me").each( function(){
// load image
var a = $.ajax({
url: 'give_me_photos.php',
data: {img: photo_id},
success: function(html){
photo_by_id(photo_id), img.append(html);
}
});
ajax_requests[photo_id] = a;
});
3)画面外への読み込みをキャンセルする
for( id in ajax_requests ) {
if ( ! is_in_visible_area(id) ) {
ajax_requests[id].abort();
}
}
もちろん、画像が既にロードされているかどうかのチェックも追加します(例えば、クラス「ロード」)
スタックを使用してAjaxリクエストを管理します(つまり、パラレルではなくシリアルでロードすることになりますが、それだけの価値はあります)
スクロール停止時に、300ms待機してから、ビュー領域内のすべての画像をスタックにプッシュします
ユーザーがスクロールするたびに、スタックが実行されているかどうかを確認します。 (fyi-すべてのajaxコールを殺す代わりに、特定のURLへのすべてのリクエストを停止できます。また、ページ上の他のリクエストを停止しないように正規表現を使用できます)
既存のスタックが実行されている場合-最上位のスタックを除くすべてのイメージをポップします。
すべてのajax呼び出しで-beforeSend()イベントをバインドして、スタックから特定の画像を削除します
今は遅いですが、仕事で非常に似たようなことをしました。詳細なコードが必要な場合はお知らせください。
乾杯!
たぶん、ロードを停止することを示すdb(またはより良いのはmemcached)のフィールドをチェックするphpスクリプトを介して画像を提供できます。スクリプトは画像をチャンクに分割し、各チャンクの間に一時停止し、特定のリクエストの停止フラグがそうであるかどうかを確認します。設定されている場合、A 204でヘッダーを送信しますが、ブラウザが取得するとすぐに受信を停止するコンテンツはありません。
ただし、これは少し過剰な場合があります。
ところで、うまくいくかもしれない別のアイデア:
1)新しいiframeを作成する
2)iframe内には、画像の読み込みを開始するスクリプトがあり、読み込まれたら.parent
のメソッドを呼び出します
3)必要に応じて、iframeオブジェクトで.stop
を使用してiframeコンテンツの読み込みを停止します
ソリューションはウェブワーカーかもしれません。 Webworkerを終了し、彼と接続することができます。ただし、Webworkerがブラウザの限られた接続を使用するため、アプリケーションがブロックされるという小さな問題があります。
現在、私はserviceWorkersを使用したソリューションに取り組んでいます-接続制限はありません(そうすることを望みます)