我有一个关于滚动背景图像的问题,它无休止地重复它。 我遇到的问题是它快速启动但很快变得越来越慢(口吃等)。这是代码:
var panoramaTimeOutId = null;
var panoramaPosition = null;
$('.panorama-left').mousedown(function() {
panoramaTimeOutId = setInterval(function(){
panoramaMove(8, 1)
}, 50);
}).bind('mouseup mouseleave', function() {
clearInterval(panoramaTimeOutId);
});
$('.panorama-right').mousedown(function() {
panoramaTimeOutId = setInterval(function(){
panoramaMove(8, 2)
}, 50);
}).bind('mouseup mouseleave', function() {
clearInterval(panoramaTimeOutId);
});
function panoramaMove(amount, direction)
{
var panorama = document.getElementsByClassName('panorama_foto')[0];
if(panoramaPosition == null)
{
panoramaPosition = panorama.style.backgroundPosition;
panoramaPosition = parseInt(panoramaPosition[0].replace("px",""));
}
if(direction == 1)
{
panoramaPosition = panoramaPosition + amount;
panorama.style.backgroundPosition = panoramaPosition+"px";
}
else
{
panoramaPosition = panoramaPosition - amount;
panorama.style.backgroundPosition = panoramaPosition+"px";
}
}
我已经尝试了一些优化的东西。就像用标准的javascript编写函数一样。在仅通过仅包含简单int的变量递增它之前,仅计算一次panoramaPosition。但它仍然口吃。
我还尝试更改间隔时间和px的数量,但它仍然在某些计算机上断断续续。例如,该网站是专为平板电脑上的平板电脑而设计的,它在电脑上断续续续,我不会对其进行编程。并且它必须在平板电脑上正常工作。
这是一个JSbin示例: http://jsbin.com/upociv/1/edit
希望有人可以提供有关如何优化此提示或一般性建议如何改进它的提示。
快速注意:Ipad(1/2/3)必须支持所有星系片,即8+ firefox chrome等。
答案 0 :(得分:2)
不要使用越来越多的像素移动panoramaPosition,而是尝试将其移动panoramaPosition % (image width)
。
通过这种方式,您不会让浏览器尝试无形地平铺从左侧开始10,000像素的背景图像 - 相反,它将永远不必将其平铺两次以上。 (您还可以避免整数溢出错误的小但非零的可能性。)
if(direction == 1)
{
panoramaPosition = panoramaPosition + amount;
panorama.style.backgroundPosition = (panoramaPosition%1277)+"px";
}
else
{
panoramaPosition = panoramaPosition - amount;
panorama.style.backgroundPosition = (panoramaPosition%1277)+"px";
}
http://jsbin.com/upociv/2/edit
但是,如果你可以在CSS3中实现它,你应该 - Modernizr允许你在JavaScript中检测浏览器是否支持CSS3转换和转换。
答案 1 :(得分:1)
jQuery 有很大的开销,所以我一直在玩重写它,因为我的评论不使用 jQuery 。另外,要尽可能地缓存。调用Panorama
会返回一个 Object ,它在属性中包含所有内容。前两个参数是必需的。
我为 addEventListener 做了兼容性的事情我调用了listen
,你可能还需要一个用于 getElementsByClassName 的颜色。
function Panorama(fullheight, fullwidth, foto, left, right) {
var panorama = {};
// crossbrowser listener
function listen(node, ev, fn) {
var a = ev.split(' '), i;
if (node.addEventListener)
for (i = 0; i < a.length; ++i)
node.addEventListener(a[i], fn);
else
for (i = 0; i < a.length; ++i)
node.attachEvent('on' + a[i], fn);
}
// short convert (px?) string to number, might be useful
function Xpx(s) {
return parseFloat(s.replace(/[^\d.]/, ''));
}
// movement
function move(amount, direction) {
if(direction) {
panorama.position += amount;
if (panorama.position > panorama.width)
panorama.position %= panorama.width;
foto.style.backgroundPosition = panorama.position + 'px';
}
else {
panorama.position -= amount;
if (panorama.position < 0)
panorama.position = panorama.width - ((-panorama.position) % panorama.width);
foto.style.backgroundPosition = panorama.position + 'px';
}
}
function zoom(scale) {
panorama.scale = scale;
panorama.height = scale * fullheight;
panorama.width = scale * fullwidth;
foto.style.zoom = scale;
}
panorama.move = move;
panorama.zoom = zoom;
// cache nodes
if (!foto) foto = document.getElementsByClassName('panorama_foto')[0];
if (!left) left = document.getElementsByClassName('panorama-left')[0];
if (!right) right = document.getElementsByClassName('panorama-right')[0];
panorama.node = {
foto: foto,
left: left,
right: right
};
// panorama scaled size info
panorama.height = fullheight;
panorama.width = fullwidth;
panorama.scale = 1;
// values
panorama.timeout = null;
panorama.position = 0;
// left
listen(left, 'mousedown', function() {
panorama.timeout = setInterval(
function(){ move(8, 1); },
50
);
});
listen(left, 'mouseup mouseout', function() { clearInterval(panorama.timeout); });
// right
listen(right, 'mousedown', function() {
panorama.timeout = setInterval(
function(){ move(8, 0); },
50
);
});
listen(right, 'mouseup mouseout', function() { clearInterval(panorama.timeout); });
return panorama;
}
var pan = Panorama(414, 1277);