我有一个非常长的页面,可以在用户滚动时动态加载图像。
但是,如果用户快速滚动离开页面的某个部分,我不希望图像继续加载到页面中现在看不到的部分。
除了图像加载之外,页面上还有很多其他请求同时发生,所以在滚动事件上触发一个钝的window.stop()是不可接受的。
我试过删除&但是,清除不再在视图中的图像的img src属性,因为请求已经开始,图像会继续加载。
请记住,当用户快速滚动浏览页面的那一部分时,图像src已填入。一旦过去,我无法在不使用window.stop()的情况下从停止加载中获取该图像。清除src不起作用。 (Chrome& FF)
类似的帖子我发现接近,但似乎没有解决这个问题:
答案 0 :(得分:17)
正如nrabinowitz所述,你要做的是错误的做法。您不能只是“取消”图像的加载过程(将src
属性设置为空字符串not a good idea)。事实上,即使你可以,这样做只会让事情变得更糟,因为你的服务器会不断发送会被取消的数据,增加它的负载因子并减慢它的速度。另外,请考虑一下:
通常,计算机问题只是设计问题。
** 编辑 **
这是一个想法:
您的页面应显示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 :(得分:12)
好吧,我的想法:
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>
答案 2 :(得分:2)
您可以使用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();
}
}
当然,还要添加一些检查图像是否已经加载(例如“加载”类)
答案 3 :(得分:1)
使用堆栈来管理ajax请求(意味着你将有串行加载而不是并行,但值得)
在滚动停止时,等待300毫秒,然后将视图区域内的所有图像推入堆栈
每次用户滚动检查堆栈是否正在运行。 (fyi - 你可以停止对特定网址的所有请求,而不是杀死所有的ajax调用。你也可以使用正则表达式,因此它不应该停止页面上的任何其他请求)
如果现有堆栈正在运行 - 请弹出除最顶层之外的所有图像。
在所有ajax调用上 - 绑定beforeSend()事件以从堆栈中删除该特定图像
现在已经很晚了,但我们在工作中做了类似的事情 - 如果您需要详细的代码,请告诉我。
干杯!
答案 4 :(得分:0)
1)创建一个新的iframe
2)iframe内部有开始加载图片的脚本,加载后,调用.parent
方法
3)在需要时,使用iframe对象上的.stop
停止加载iframe内容
答案 5 :(得分:0)
也许你可以通过一个php脚本来提供图像,这个脚本会检查数据库中的一个字段(或者更好的是memcached),它会指示停止加载。脚本会将图像分成块并在每个块之间暂停,并检查特定请求的停止标志是否为。如果已设置,则发送标题为A 204无内容,一旦浏览器获得它将停止接收。
虽然这可能有点过时了。
答案 6 :(得分:0)
解决方案可能是一个网络工作者。一个webworker可以终止并与他联系。 但是网络工作者使用浏览器的有限连接存在一个小问题,因此应用程序将被阻止。
现在我正在与serviceWorkers合作解决方案 - 他们没有连接限制(我希望如此)