0

我正在处理一个具有固定位置的简单侧导航的页面,设置为顶部:30%。我需要做的是在页面底部我想淡出菜单,这样它就不会与页脚重叠,下面的代码有效,但我认为它正在检查滚动,需要很长时间才能计算你快速向下滚动。

是否有更快/更轻量级的方法来计算何时隐藏侧导航?我不熟悉去抖动,但这有帮助吗?

元素:

.body-container-wrapper - total height of page
.footer-container-wrapper - total height of the footer that we want the nav to be hidden at
.internal-side-nav - the menu position: fixed, top: 30%, right: 0

示例页面:http ://hsb1.hubspot.com/profile-page-template

脚本:

<script type="text/javascript">
$(document).scroll(function () {
   var y = $(this).scrollTop();
   if (y < $('.body-container-wrapper').outerHeight() - $('.footer-container-   wrapper').outerHeight() - 400 ) {
    $('.internal-side-nav').fadeIn();
 } else {
    $('.internal-side-nav').fadeOut();
 }
});
</script>
4

2 回答 2

0

I hadn't heard of debounce so I had to look it up. It could potentially help, but that would be an extra plugin you'd have to include and maintain and it might not work exactly how you want (I didn't see anything indicating that it does "bunches or time frames", just seemed to be bunches, which means it might fire late on you).

Instead, what you could do is throttle it yourself with a little bit of timing.

var scrollTimeInterval = 200; // how often we allow the action to trigger, in ms.
var lastScrollTime = 0;
var scrollTimeoutId = null;
$(document).scroll(function () {
   var now = (new Date()).getTime();
   var dScrollTime = now - lastScrollTime;
   lastScrollTime = now;

   if (dScrollTime < scrollTimeInterval) {
        // Set a timeout so we catch the last one.
        scrollTimeoutId = setTimeout(function() { $(document).scroll(); }, scrollTimeInterval - dScrollTime);
        return; // too soon, so we'll skip
   }

   // Clear any potentially pending timeout.
   clearTimeout(scrollTimeoutId);

   var y = $(this).scrollTop();
   if (y < $('.body-container-wrapper').outerHeight() - $('.footer-container-   wrapper').outerHeight() - 400 ) {
    $('.internal-side-nav').fadeIn();
 } else {
    $('.internal-side-nav').fadeOut();
 }
});

With this, the scroll event simply won't do anything if it hasn't been a certain amount of time since it last triggered. To ensure we catch the last scroll event (the last one before they stopped scrolling), I added a timeout which will trigger the scroll event one last time. We also have to make sure to clear that if we handle another scroll event before it fires (so we don't double up on it).

You can control the time interval it allows with the first variable. If 200ms feels a bit sluggish, you can reduce it to 100ms or 50ms and see if that gives a better balance.

Hope that helps.

于 2014-01-30T00:43:11.130 回答
0

处理滚动事件,在某些情况下,您无能为力。

解决方案 1:在每次迭代时自行取消的 setTimeout

我相信这种方法是最有效的,但对你来说可能并不理想,因为在淡出之前,sidenav 仍然会在视觉上与页脚重叠 300 毫秒。

var scrollTimeout = false;
$(document).scroll(function(){
  clearTimeout(scrollTimeout);
  var _this = this; // for the setTimeout function to know what "this" is
  scrollTimeout = setTimeout(function(){
    // your original code block goes here
    // BUT, replace "this" with "_this"
  }, 300);
});

以上基本上只在用户没有滚动至少 300 毫秒时运行您的代码。

解决方案2:只是好的旧优化(没有太多技巧)

此解决方案应立即隐藏 sidenav,但仍会在每个滚动条上运行,只是做得更少

var myScrollEvent = (function(){
  var $win = $(window);
  var $foot = $('.footer-container-wrapper');
  var footer_top = $foot.offset().top; // where on the page the footer begins
  var $nav = $('.internal-side-nav');
  var nav_height = $nav.height(); // maybe use outerHeight(true)?...who knows, only you
  var is_hidden = false;

  // this is the actual function we want to run on-scroll
  return function(){
    // jquery, even on fixed elements, still seems to account for scroll position
    // when calculating top offset value, below is the coordinate of the bottom of the nav
    var nav_bottom = $nav.offset().top + nav_height;

    // if the bottom coord of the nav is lower than the top coord of the footer
    if(nav_bottom > footer_top && !is_hidden){
      is_hidden = true;
      // hide it code
    }else if(is_hidden){
      is_hidden = false;
      // show it code
    }
  };

})();

$(window).scroll(myScrollEvent);

这里的想法是缓存一些变量,并以稍微不同的方式进行计算。你的方式似乎没有任何错误,但这只是一种选择。请注意,使用这种方法,我们假设导航高度永远不会改变。

如果您愿意,也可以随时将这两种解决方案结合起来。

另外,请注意,我没有做过任何 browser-2-browser 测试,所以如果有任何缺陷,当然让我知道。

于 2014-01-30T01:00:44.017 回答