隐藏在中间的粘滞菜单错误

时间:2019-01-29 00:24:10

标签: jquery html css menu header

我有一个<header>,它依次包含两个div,如下图所示:

Fig 07 在div A的上半部分和div B的下半部分中。我想做的是一个粘性菜单,即当下div的上半部分(红色)为零时,整个标头的位置固定,使用浏览器窗口隐藏上层div(蓝色)。那是: Fig 07-02 这是我的代码:

    $(document).ready(function(){
    
        let smenu = $('.divB');
        stickyMenu(smenu);
    
        function stickyMenu(menu){
            $(window).on('scroll', function(){
                if($(this).scrollTop() > menu.offset().top) menu.addClass('menu-fixed');
                else menu.removeClass('menu-fixed');
            });
        }
    });
    body {
        height: 8000px;
    }
    
    header{
        background-color: transparent;
        width: 95%;
        margin: auto;
        overflow: hidden;
        transform: translateY(20px);
    }
    
    header .divA{
        width: 100%;
        background-color: #FFF;
        z-index: 1;
        overflow: hidden;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
        height: 40px;
        width: 100%;
        background-color: red;
    }
    
    header .divB{
        width: 100%;
        background-color: #FFF;
        z-index: 1;
        overflow: hidden;
        border-bottom-left-radius: 5px;
        border-bottom-right-radius: 5px;
        height: 40px;
        width: 100%;
        background-color: green;
    }
    
    /*This class is to "stick" the menu on the top*/
    .menu-fixed{
        position: fixed;
        z-index: 999;
        width: 100%;
        top: 0;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
    <div class="divA">
        divA
    </div>
    <div class="divB">
        divB
    </div>
    </header>

问题在于,滚动时,完整的标题会离开窗口(向上)并卡在其中,直到我向下滚动为止。

1 个答案:

答案 0 :(得分:1)

css和javascript有很多问题。 首先,在CSS中使用position: fixed内部具有transform属性的元素将消除“固定”行为。 Check this answer on Stackoverflow

在您的JS中,您评估每个滚动事件的偏移量。这将导致混乱,因为应用于divB“菜单固定”的类会更改offset()。top,并且每次滚动事件都会读取新的top偏移量。因此,正如我在下面的代码中所做的那样,将顶部偏移量保持在滚动事件之外。这将保留对原始顶部偏移的引用,而不是更新每个会导致不良效果的事件。

$(document).ready(function() {

  let smenu = $('.divB');
  stickyMenu(smenu);

  function stickyMenu(menu) {
  // Keep offset value out of scroll event
    var top = menu.offset().top;
    $(window).on('scroll', function() {
      var hasMoved = $(this).scrollTop() > top;
      (hasMoved == true) ? menu.addClass('menu-fixed'): menu.removeClass('menu-fixed');

    });
  }
});
body {
  height: 8000px;
}

header {
  background-color: transparent;
  width: 95%;
  margin: auto;
  /* Transform will act as a containing block for fixed position elemenets
   transform: translateY(20px);*/
 position: relative;
 top: 20px;
  overflow: hidden;
}

header .divA {
  width: 100%;
  background-color: #FFF;
  z-index: 1;
  overflow: hidden;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  height: 40px;
  width: 100%;
  background-color: red;
}

header .divB {
  width: 100%;
  background-color: #FFF;
  z-index: 1;
  overflow: hidden;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
  height: 40px;
  width: 100%;
  background-color: green;
}


/*This class is to "stick" the menu on the top*/

.menu-fixed {
  position: fixed;
  z-index: 999;
  width: 100%;
  top: 0;
  left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
  <div class="divA">
    divA
  </div>
  <div class="divB">
    divB
  </div>
</header>