滚动功能不会产生平滑过渡

egr*_*103 5 html javascript css jquery

我有一个固定的DIV #scroll-up,它是浏览器窗口的100%高度.我有另一个DIV #next-prev坐在它下面.一旦#next-prev进入视野,我希望#scroll-upDIV开始向上滚动.我的代码打击了这一点,但是只要#next-prev在视野中就会#scroll-up毫无理由地跳起来.效果应该是无缝的.

我该如何防止跳跃?

我在这里设置了jsFiddle问题的演示:http://jsfiddle.net/sya0jr6p/1/


JS

使用jQuery Visible插件检测#next-prev何时在视图中.

$(window).scroll(function() {

    if ($('#next-prev').visible(true)) {
        console.log ( '#next-prev visible' );

        // Initiate scroll up of '#scroll-up' when '#next-prev' is in the viewport
        var $tagline = $('#scroll-up');
        var windowScroll;

        // Function
        function slidingTitle() {

            //Get scroll position of window
            windowScroll = $(this).scrollTop();

            $tagline.css({
                'top' : -(windowScroll/3)+"px"
            });

        }
        // Initiate
        slidingTitle();

    } else {
        console.log ( '#next-prev not visible' );
         // The element is NOT visible, do something else

    }

});
Run Code Online (Sandbox Code Playgroud)

UPDATE

进一步测试后,仅当#nav-wrap屏幕上尚未显示跳转时才存在.如果它在屏幕上,则跳转不会发生并按预期工作.

我注意到的另一件事; 当您第一次加载页面时,AND #nav-wrap尚未显示在屏幕上.正常向下滚动页面直到你看到#scroll-up跳起来,如果继续向下滚动,你会看到我想要发生的事情.#scroll-up滚动正常.但是,如果在跳转后向上滚动页面到最顶部,您会注意到位置与#scroll-up第一次加载页面时的位置不同.计算错了吗?或者代码的顺序是错的?只是一些想法......

UPDATE

这是一个关于我希望滚动如何工作的动画GIF,已经给出的动画答案不直观:

在此输入图像描述

Mik*_*lRo 5

您看到跳转的原因是您只需将当前窗口滚动位置#next-prev除以 3 并将其设置为最高值#scroll-up...当您到达时窗口滚动#next-prev将大于 0,因此滚动被分割三倍也将大于零,并#scroll-up会立即得到一个(大)负值top

我不知道你从哪里得到的除以三 - 这会导致元素滚动速度变慢(又名视差效应) - 这意味着即使没有跳跃并#scroll-up开始在正确的点滚动,它也会还涵盖的三分之二#next-prev曾经#next-prev是充分考虑到。所以我不认为你真正想要的视差效果...

我认为你想要的是: 的top#scroll-up需要为零,直到#next-prev滚动到视图的第一个像素,然后随着#next-prev“更多”进入视图而逐渐增长,确保它完全保持在#next-prev......即。top of#scroll-up需要为 0 减去像素数#next-prev的 top 来自视口的底部 - 当然如果#next-prev仍然完全低于视口,则始终为零。

这是实现这一目标的一种方法......

(function($) {
  $(window).scroll(function() {
    //Get the footer position relative to the document
    var footer_offset = $("#footer").position().top;
    //Get the window height (viewport height)
    var window_height = $(window).height();
    //Get the current scroll position
    var window_scroll = $(window).scrollTop();
    //Calculate the bottom of the window relative to the document
    var window_bottom_offset = window_scroll + window_height;
    //Calculate "how much" of the footer is above the bottom of the window
    var footer_visible_pixels = window_bottom_offset - footer_offset;
    //Default #semistuck's position to top: 0px
    var semistuck_top = 0;
    //But if the footer is above the bottom of the screen...
    if (footer_visible_pixels > 0) {
      //...move #semistuck up by the same amount of pixels
      semistuck_top = -footer_visible_pixels;
    }
    //Actually move it
    $("#semistuck").css('top', semistuck_top + 'px');
    //Just to see each step of the calculation
    console.log(footer_offset, window_height, window_scroll, window_bottom_offset, footer_visible_pixels, semistuck_top);
  });
}(jQuery));
Run Code Online (Sandbox Code Playgroud)
body,
html {
  margin: 0;
}
#semistuck,
#loooooong,
#footer {
  margin: 0;
  padding: 4em 1em;
  text-align: center;
  box-sizing: border-box;
}
#semistuck {
  position: fixed;
  width: 50%;
  height: 100%;
  top: 0;
  left: 0;
  background: #afa;
}
#loooooong {
  height: 2000px;
  margin-left: 50%;
  width: 50%;
  background: repeating-linear-gradient(45deg, #606dbc, #606dbc 100px, #465298 100px, #465298 200px);
}
#footer {
  background: #faa;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="semistuck">
  This is stuck until the<br>footer scrolls into view
</div>
<div id="loooooong"></div>
<div id="footer">
  When this gets into<br>view #semistuck will<br>get out of its way
</div>
Run Code Online (Sandbox Code Playgroud)

显然上面的代码比需要的更冗长,但我觉得计算中非常小的增量使得发生的事情更清楚......

这是更简短的形式:

var footer_visible_pixels = $(window).scrollTop() + $(window).height() - $("#footer").position().top;
$("#semistuck").css('top', (footer_visible_pixels > 0 ? -footer_visible_pixels : 0) + 'px');
Run Code Online (Sandbox Code Playgroud)

唔...

...想想看,您实际上可能想要视差效果,但只是希望页脚位于顶部,所以这里有一个稍微修改的版本,它提供了一个有点酷的效果:

var footer_visible_pixels = $(window).scrollTop() + $(window).height() - $("#footer").position().top;
$("#semistuck").css('top', (footer_visible_pixels > 0 ? -footer_visible_pixels : 0) + 'px');
Run Code Online (Sandbox Code Playgroud)
(function($) {
  $(window).scroll(function() {
    //Get the footer position relative to the document
    var footer_offset = $("#footer").position().top;
    //Get the window height (viewport height)
    var window_height = $(window).height();
    //Get the current scroll position
    var window_scroll = $(window).scrollTop();
    //Calculate the bottom of the window relative to the document
    var window_bottom_offset = window_scroll + window_height;
    //Calculate "how much" of the footer is above the bottom of the window
    var footer_visible_pixels = window_bottom_offset - footer_offset;
    //Default #semistuck's position to top: 0px
    var semistuck_top = 0;
    //But if the footer is above the bottom of the screen...
    if (footer_visible_pixels > 0) {
      //...move #semistuck up by the same amount of pixels
      semistuck_top = -footer_visible_pixels/3;
    }
    //Actually move it
    $("#semistuck").css('top', semistuck_top + 'px');
    //Just to see each step of the calculation
    console.log(footer_offset, window_height, window_scroll, window_bottom_offset, footer_visible_pixels, semistuck_top);
  });
}(jQuery));
Run Code Online (Sandbox Code Playgroud)
body,
html {
  margin: 0;
}
#semistuck,
#loooooong,
#footer {
  margin: 0;
  padding: 4em 1em;
  text-align: center;
  box-sizing: border-box;
}
#semistuck {
  position: fixed;
  width: 50%;
  height: 100%;
  top: 0;
  left: 0;
  background: #afa;
}
#loooooong {
  height: 2000px;
  margin-left: 50%;
  width: 50%;
  background: repeating-linear-gradient(45deg, #606dbc, #606dbc 100px, #465298 100px, #465298 200px);
}
#footer {
  background: #faa;
  position: relative;
}
Run Code Online (Sandbox Code Playgroud)

与最初的建议相比,只有两件事发生了变化:

  1. 我已经添加position: relative到页脚
  2. 我把消极top#semistuck三个

笔记

这些都不适用于 iPhone、iPad 以及可能大多数其他触摸设备。它们只是滚动期间不会触发任何滚动事件,而只会. 因此,如果对移动设备的支持是一个问题,您应该检测这些并提供回退 - 替代方案是仅在滚动结束后才会发生的非常跳跃的效果。据我所知,没有解决方法,根据情况处理它的最佳方法可能是:

  1. 只是降级到更简单的东西
  2. 使用其他答案中提供的动画解决方案之一 - 但仅限于不支持连续滚动事件的设备