代码之家  ›  专栏  ›  技术社区  ›  Héctor M.

中间隐藏的粘性菜单出错

  •  1
  • Héctor M.  · 技术社区  · 6 年前

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

    Fig 07 上半部分是A区,下半部分是B区。我想做的是一个粘性菜单,当下半部分(红色)为零时,整个标题有一个固定的位置,用浏览器窗口隐藏上半部分(蓝色)。即: 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 回复  |  直到 6 年前
        1
  •  1
  •   Kalimah Laxman Edara    6 年前

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

    在JS中,计算每个滚动事件的偏移量。这将导致混淆,因为应用于divB“menu fixed”的类更改了offset().top,并将导致scroll事件每次都读取一个新的top offset。因此,正如我在下面的代码中所做的那样,将顶部偏移量保留在scroll事件之外。这将保留对原始顶部偏移的引用,而不是更新将导致不希望的效果的每个事件。

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