简体   繁体   English

垂直滚动视差背景效果

[英]Vertical scrolling parallax background effect

Background 背景

I have been asked to write a script that will create a vertical scrolling parallax background effect for a project. 我被要求编写一个脚本,该脚本将为项目创建垂直滚动视差背景效果。 My initial attempt looks a little something like this: 我最初的尝试看起来像这样:

(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 });

This code does give the required effect, but the bind on the scroll event is a real performance drain. 这段代码确实提供了所需的效果,但是滚动事件上的绑定确实消耗了性能。

Question

Part 1. How could I change my plugin to be more efficient? 第1部分。如何更改插件以提高效率? Part 2. Are there any resources (books, links, tutorials) I can read to find out more? 第2部分。是否可以阅读任何资源(书籍,链接,教程)以了解更多信息?

You may try something like: 您可以尝试以下方法:

(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);

So the browser will not scroll the background if there are multiple scroll events is sequence. 因此,如果有多个滚动事件为序列,浏览器将不会滚动背景。 I wrote func outside the event handler to avoid the creation of a new closure in every event. 我在事件处理程序外部编写了func ,以避免在每个事件中创建新的闭包。

You should make the actual "scroll" event handler start a timer: 您应该使实际的“滚动”事件处理程序启动一个计时器:

    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;
        });
    });

Or something like that. 或类似的东西。 This way, you're only doing the DOM manipulation at most 10 times a second. 这样,您每秒最多只能进行10次DOM操作。

One thing you could do is instead of: 您可以做的一件事是:

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

You can create the window jQuery object outside of the scroll event. 您可以在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"
                });
            }
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM