垂直滚动视差背景效果

时间:2011-09-22 20:45:48

标签: javascript jquery

背景

我被要求编写一个脚本,为项目创建垂直滚动视差背景效果。我最初的尝试看起来像这样:

(function($){
    $.fn.parallax = function(options){
        var $$ = $(this);
        offset = $$.offset();
        var defaults = {
            "start": 0,
            "stop": offset.top + $$.height(),
            "coeff": 0.95
        };
        var opts = $.extend(defaults, options);
        return this.each(function(){
            $(window).bind('scroll', function() {
                windowTop = $(window).scrollTop();
                if((windowTop >= opts.start) && (windowTop <= opts.stop)) {
                    newCoord = windowTop * opts.coeff;
                    $$.css({
                        "background-position": "0 "+ newCoord + "px"
                    });
                }
            });
        });
    };
})(jQuery);

// call the plugin
$('.lines1').parallax({ "coeff":0.65 });
$('.lines1 .lines2').parallax({ "coeff":1.15 });

此代码确实提供了所需的效果,但滚动事件上的绑定是一个真正的性能消耗。

问题

第1部分。如何更改插件以提高效率? 第2部分。是否有任何资源(书籍,链接,教程)我可以阅读以了解更多信息?

3 个答案:

答案 0 :(得分:2)

您可以尝试以下方式:

(function($){
    $.fn.parallax = function(options){
        var $$ = $(this);
        offset = $$.offset();
        var defaults = {
            "start": 0,
            "stop": offset.top + $$.height(),
            "coeff": 0.95
        };
        var timer = 0;
        var opts = $.extend(defaults, options);
        var func = function(){
            timer = 0;
            var windowTop = $(window).scrollTop();
            if((windowTop >= opts.start) && (windowTop <= opts.stop)) {
                newCoord = windowTop * opts.coeff;
                $$.css({
                    "background-position": "0 "+ newCoord + "px"
                });
            }
        };
        return this.each(function(){
            $(window).bind('scroll', function() {
                window.clearTimeout(timer);
                timer = window.setTimeout(func, 1);
            });
        });
    };
})(jQuery);

因此,如果有多个滚动事件是序列,浏览器将不会滚动背景。我在事件处理程序之外写了func以避免在每个事件中创建一个新的闭包。

答案 1 :(得分:1)

你应该让实际的“scroll”事件处理程序启动一个计时器:

    var opts = $.extend(defaults, options);
    var newCoord = null, prevCoord = null;

    setInterval(function() {
      if (newCoord !== null && newCoord !== prevCoord) {
                $$.css({
                    "background-position": "0 "+ newCoord + "px"
                });
                prevCoord = newCoord;
       }
    }, 100);

    return this.each(function(){
        $(window).bind('scroll', function() {
            windowTop = $(window).scrollTop();
            if((windowTop >= opts.start) && (windowTop <= opts.stop)) {
                newCoord = windowTop * opts.coeff;
            }
            else
                prevCoord = newCoord = null;
        });
    });

或类似的东西。这样,你每秒最多只能操作DOM 10次。

答案 2 :(得分:0)

你可以做的一件事是代替:

            $(window).bind('scroll', function() {
                windowTop = $(window).scrollTop();
                if((windowTop >= opts.start) && (windowTop <= opts.stop)) {
                    newCoord = windowTop * opts.coeff;
                    $$.css({
                        "background-position": "0 "+ newCoord + "px"
                    });
                }
            });

您可以在scroll事件之外创建窗口jQuery对象。

        $window = $(window); //create jQuery object
        $window.bind('scroll', function() {
            windowTop = $window.scrollTop();
            if((windowTop >= opts.start) && (windowTop <= opts.stop)) {
                newCoord = windowTop * opts.coeff;
                $$.css({
                    "background-position": "0 "+ newCoord + "px"
                });
            }
        });