3

我有一个关于滚动不断重复的背景图像的问题。我遇到的问题是它开始很快但很快变得越来越慢(口吃等)。这是代码:

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 的变量对其进行递增。然而它仍然结结巴巴。

我还尝试更改间隔时间和 px 数量,但在某些计算机上仍然卡顿。例如,该网站是为平板电脑上的平板电脑设计的,它在我没有编程的电脑上口吃。它必须在平板电脑上正常工作。

这是一个 JSbin 示例:http: //jsbin.com/upociv/1/edit

希望有人可以提供有关如何优化此功能的提示或一般性建议,我将如何改进它。

快速说明:必须由 Ipad (1/2/3) 所有 Galaxy 平板电脑和 8+ firefox chrome 等支持。

4

2 回答 2

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 转换和转换。

于 2013-07-17T17:17:32.670 回答
1

jQuery的开销很大,所以自从我发表评论以来,我一直在尝试重写它以不使用jQuery 。另外,要尽可能多地缓存。调用Panorama返回一个对象,该对象在属性中整齐地包含所有内容。前两个参数是必需的。

我为我调用的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);
于 2013-07-17T17:54:38.660 回答