javascript - 自定义视差滚动问题

标签 javascript jquery parallax

我有一个网站的自定义视差滚动部分。不同的地方都有对话气泡,并且它们都以不同的速度滚动。

http://goo.gl/jZhVrJ (您会在页面中间找到对话气泡)

当您第一次向下滚动时,一切正常,并且元素位于我想要的位置。下面是它的外观的屏幕截图:

enter image description here

但是,如果您滚动回到顶部,然后再次向下滚动 - 每次返回到该部分时,气泡的位置都会不同。如果你这样做的次数足够多,你就可以将对话气泡完全置于该内容 block 之外。这是最终看起来不正确的屏幕截图: enter image description here

这里的一般概念是我已经定位了每个气泡。然后,当用户滚动时,代码会更改每个气泡的“top”属性。如果用户向下滚动,则会减少“顶部”值。如果它们向上滚动,则会增加“顶部”值。每个气泡都是一个不同的放大镜,因此气泡看起来以不同的速度移动。

这也使用了“inview”插件,因此滚动仅在用户查看该 block 时发生。

这是执行视差滚动的 JS 代码:

var $window = $(window);
var windowHeight = $window.height();
var $quoteBG = $('.philosophy');
var quote1 = $("#quote1");
var quote2 = $("#quote2");
var quote3 = $("#quote3");
var quote4 = $("#quote4");
var quote5 = $("#quote5");
var quote6 = $("#quote6");
var quote7 = $("#quote7");
var quote8 = $("#quote8");
var quote9 = $("#quote9");

var scrolldirection = '-';
var lastScrollTop = 0;
var modifier = '-';
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       scrolldirection = 'down';
   } else {
      scrolldirection = 'up';
   }
   lastScrollTop = st;
});

//function to be called whenever the window is scrolled or resized
function Move(){ 

    //if the second section is in view...
    if($quoteBG.hasClass("inview")){

        if ( scrolldirection == 'down' ) {
            modifier = '-';
        } else {
            modifier = '+';
        }

        quote1.css( 'top', modifier+'=2');
        quote2.css( 'top', modifier+'=1');
        quote3.css( 'top', modifier+'=3');
        quote4.css( 'top', modifier+'=2.1');
        quote5.css( 'top', modifier+'=2.5');
        quote6.css( 'top', modifier+'=3');
        quote7.css( 'top', modifier+'=2');
        quote8.css( 'top', modifier+'=1.5');
        quote9.css( 'top', modifier+'=3');

    }
}

$window.resize(function(){ //if the user resizes the window...
    Move(); //move the background images in relation to the movement of the scrollbar
});        

$window.bind('scroll', function(){ //when the user is scrolling...
    Move(); //move the background images in relation to the movement of the scrollbar
});

最佳答案

我必须将以下代码添加到您的 fiddle 中才能使其正常工作:

$quoteBG.on('inview', function (evt, isInView) {
    if (isInView) {
        $quoteBG.addClass("inview");
    }
    else {
        $quoteBG.removeClass("inview");
    }
});

修复版本在这里:http://jsfiddle.net/up15ns6t/2/

使用后,我发现了几个问题。

第一个问题是我从一开始就怀疑的问题:您的位置计算是通过每次滚动事件触发时添加或减去固定数量来完成的。这样做的问题是,无论窗口滚动多远,您都会进行相同的调整。例如,当窗口在事件之间滚动 1 像素以及在事件之间滚动 100 像素时,您将第一个引号调整 2 像素。这使得结果具有不确定性。

如果我这样做,我会尝试提出一种确定性算法,根据窗口的滚动位置计算每个引号的位置。或者,您可以尝试使用加/减方法,但在计算中包括自上次事件以来窗口滚动的量。

我在使用它时注意到的另一件事是,当父 div (.philosophy) 隐藏时,位置不会更新。因此,如果你不断地将其滚动进出 View ,报价就会逐渐爬升。此行为是由这行代码引起的:

if($quoteBG.hasClass("inview")){

您需要在该逻辑中包含“或之前已在 View 中”的情况。

我现在没有更多的时间来玩它并想出一个工作版本,但也许你可以使用这些想法来让它工作。

更新1
我在你的 fiddle 中创建了一个简单的确定性算法,并将其应用到单引号 div 中,以防止事情变得过于困惑。它首先计算可见的背景 div 的数量:

var windowHeight = $window.height();
var backgroundTop = Math.round($quoteBG.offset().top);
var st = $window.scrollTop();
var visibleHeight = (windowHeight + st) - backgroundTop;

如果背景 div 低于视口(viewport)底部,则 visibleHeight 值将为负数。一旦变为正值,我就会根据该值计算报价 div 的新位置。

在页面加载时,我记录了引用 div 的初始位置并为其定义了运动比率:

var motion1 = 0.5;
var baseTop1 = $quote1.position().top;

滚动时,我将它们与 visibleHeight 结合使用来计算引用的位置:

var position1 = baseTop1 + Math.round(visibleHeight * motion1)

因此,在此示例中,引文以背景速度的一半向下滚动(由于 motion1 = 0.5)。

更新的 fiddle 在这里:http://jsfiddle.net/up15ns6t/5/

需要注意的一点是,位置计算不处理报价超出背景底部的情况。如果您想在其下方放置某些内容,则可能需要添加一些检查以防止报价向下移动得太远。

关于javascript - 自定义视差滚动问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32619949/

相关文章:

javascript - 未捕获的语法错误 : Unexpected token = (Chrome)

php - 如何使用 Jquery 发布数组

javascript - 如何更快地索引 Javascript 中的对象数组?

javascript - 根据滚动条的位置更改 div 的背景,而不是看起来像已加载

javascript - 更改滚动 : jerky movement vs. 平滑移动上的 CSS 变换

javascript - JQuery 选择器未选择 EmberJS View 中的列表项

javascript - 传递变量 VS 传递值

javascript - 使用 jquery 在特定 DIV 中滚动事件

javascript - 动画背景位置不起作用

javascript - 页面部分出现视差,其余部分正常滚动