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

时间:2015-08-06 09:42:58

标签: javascript jquery html css

我有一个固定的DIV #scroll-up,它是浏览器窗口的100%高度。我有另一个DIV #next-prev位于它下面。一旦#next-prev进入视图,我希望#scroll-up DIV开始向上滚动。我的代码打击会这样做,但只要#next-prev在视图#scroll-up中,就会无缘无故地跳起来。效果应该是无缝的。

如何防止跳跃?

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

JS

使用jQuery Visible plugin检测#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

    }

});

更新

进一步测试后,当#nav-wrap已经在屏幕上时,仅存在跳转。如果它在屏幕上,则跳转不会发生并按预期工作。

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

更新

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

enter image description here

5 个答案:

答案 0 :(得分:3)

您看到跳转的原因是,您只需将#next-prev进入视图3时将当前窗口滚动位置分开,并将其设置为#scroll-up的顶部值...窗口滚动当您到达#next-prev时将大于0,因此滚动除以3也将大于零,#scroll-up将立即获得(大)负top值。

我不知道你从哪里得到了三个除法 - 这会创建一个较慢的元素滚动(又称。视差效果) - 这意味着即使没有跳跃而且#scroll-up开始滚动在正确的位置,一旦#next-prev完全在视野中,它仍将覆盖#next-prev的三分之二...所以我认为你实际上并不想要视差效果......

我认为你想要的是: top的{​​{1}}值必须为零,直到#scroll-up的第一个像素滚动到视图中,然后随着#next-prev“更多”进入视图逐渐增长,确保它保持在#next-prev之上......即。 #next-prev的顶部需要为0减去像素数#scroll-up的顶部位于视口底部 - 如果#next-prev仍然完全位于视口下方,当然总是为零

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

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

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

以较短的形式出现同样的事情:

<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>

嗯...

...想到它你可能真的想要视差效果,但只想让页脚在顶部,所以这里有一个稍微修改过的版本,它会产生一些很酷的效果:

var footer_visible_pixels = $(window).scrollTop() + $(window).height() - $("#footer").position().top;
$("#semistuck").css('top', (footer_visible_pixels > 0 ? -footer_visible_pixels : 0) + 'px');
(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));
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;
}

与原始建议相比,只有两件事情发生了变化:

  1. 我已将<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>添加到页脚
  2. 我将position: relative的负top除以三
  3. 注意

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

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

答案 1 :(得分:0)

您需要反馈是否它是否是您的预期结果。或者你需要改进什么

&#13;
&#13;
$(window).on('scroll',function() {
    var $scrollUp = $("#scroll-up"),
        $nextDiv = $("#next-prev"),
        $divScrolled = $(this).scrollTop()/3;
    if ($nextDiv.visible(true)){
        $scrollUp.stop().animate({
            'top': - $divScrolled
        },'slow');
    }else{        
        $scrollUp.stop().animate({
            'top': 0
        },'slow');
        console.log("Nothing will be in your");
    }    
});
&#13;
html,body{ height:100%; }
#scroll-up {
    position: fixed;
	top: 0;
    background:aqua;
    height:100%;
	left: 0;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
    width: 50%;
}

.demo-purposes { padding-top:200px;}

#next-prev { 
    background:pink; 
    text-align:center; 
    width: 100%;
    top: 10px;
	overflow: hidden;
	position: relative; }
&#13;
<div id="scroll-up">
    <div class="demo-purposes"> <!-- This is just here so you can see the problem -->
        This content block should begin to scroll up when #next-prev is in the viewport. This does happen, however it isn't very smooth and this message will jump up a certain amount of pixels.</div>
</div>
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<br/>&nbsp;
<div id="next-prev">
    #next-prev DIV
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing s</p>
</div>
&#13;
&#13;
&#13;

在这里,我也给我的工作jsfiddle,以便您可以给出明确的反馈。

My Working Demo

答案 2 :(得分:0)

这有帮助吗? 目前您正在更改CSS的最高值。为什么不在顶部添加转换?请参阅小提琴示例。

    .left{
    float:left;
    padding:2px;
    }

http://jsfiddle.net/vq94s6fw/

答案 3 :(得分:0)

我认为我按照您希望的方式工作。如果不是这样,请告诉我。我在CSS中更改了#roll-up并添加了一个名为.scroll-up-fixed的额外类。

您可以在此处查看演示:http://jsfiddle.net/poj3ce51/

#scroll-up {
    position: absolute;
    background:aqua;
    height:100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    width: 50%;
}

.scroll-up-fixed {
    position: fixed !important;
}

我还将jQuery部分更改为以下内容:

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

        var $tagline = $('#scroll-up');
        var windowScroll;

        $tagline.removeClass("scroll-up-fixed");

        // Functional parallaxing calculations
        function slidingTitle() {

            //Get scroll position of window
            windowScroll = $(this).scrollTop();
            windowHeight = $(window).height();
            $tagline.css({
                'top' : (windowHeight)+"px"
            });

        }
        slidingTitle();

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

答案 4 :(得分:-1)

滚动跳转是当前浏览器的浏览器默认行为。 (除非你覆盖它)

如果你用firefox或EI9 +检查,你会看到一个平滑的滚动。

Chrome在chrome flags下有一个名为平滑滚动的设置。 (如果您使用的是铬)

搜索如何在浏览器上强制滚动。

answer可能会有所帮助。