切换div位置:固定有时会导致滚动错误

时间:2016-02-09 19:47:48

标签: jquery css html5

我有一个水平菜单,我用CSS和HTML5实现了。我有代码添加一个“固定”类,当用户滚过它时,将菜单“锁定”到屏幕顶部:

$(function(){
        // number of pixels before "locking" menu is the distance between the menu and the top of the page
        var numScroll = $("#mainMenu").offset().top;

        // toggle "fixed" class depending on scroll position, so that when menu is passed it gets locked to top of screen
        $(window).bind('scroll', function () {
            if ($(window).scrollTop() > numScroll) {
                // add fixed class and set "left" property dynamically to properly center the menu
                $('#mainMenu').addClass('fixed').css('left', function(){
                    return ($(window).width()-$(this).width())/2;
                });
            } else {
                $('#mainMenu').removeClass('fixed');
            }
        });
    });

这是“固定”类css代码:

.fixed {
    position:fixed;
    top:0;
    display:table;
    padding:0;
    /* Set high z-index so that it appears on top of anything on the page when scrolling */
    z-index: 99;
}

这很有效。问题是在某些情况下,这似乎取决于窗口/内容高度,页面“锁定”在底部之前,并且不允许您将最后一位滚动到页面末尾。当你试图滚动最后一位时,它会反弹回来。我不确定是什么导致这种情况或如何避免它。

(如有必要,您可以查看Using Beyond Compare with Version Control Systems under OS X以获取更详细的代码)

更新: previous question of mine包含所有代码,但我似乎无法复制出现在我们网站上的滚动问题。

更新2: 我实际上通过删除一些空白空间来设法复制它Here's a fiddle。你可能不得不玩输出窗口的大小,但是当最低滚动点只是导致菜单捕捉到顶部时,似乎会出现。

3 个答案:

答案 0 :(得分:3)

更新:我误解了原来的问题,所以我更新了我的答案,只是展示我如何处理滚动浏览时触发的粘贴标题。

我的建议:在菜单之前直接添加一个空的div元素(在我的例子中给它ID' menuLocator'然后检查该元素的偏移量,以便知道何时应用和删除& #39;固定'课程菜单。因为该div仍然静态地放置在菜单HTML所在的页面上,所以您的滚动事件现在可以告诉菜单应该在哪里并应用“已修复”的菜单。如果滚动超出该类,则为class。

这是我的解决方案。我知道我没有使用完全相同的HTML或CSS,它应该只是让你大致了解一种做粘贴标题的方法。



$(window).bind('scroll', function(e){
  if ($(this).scrollTop() > $('#menuLocator').offset().top) {
    $('.horizontalMenu').addClass('fixed');
  } else {
    $('.horizontalMenu').removeClass('fixed');
  }
});

#filler {
  height:2000px;
  background:lightgray;
}
.horizontalMenu {
  position:relative;
  width:100%;
  margin-bottom:5px;
}
.menuInner {
  width:80%;
  margin:0 auto;
  box-shadow:1px 1px 3px black;
  background:white;
}
.menuInner ul {
  margin:0;
  padding:0;
  list-style-type:none;
}
.menuInner li {
  display:inline-block;
  width:30%;
  text-align:center;
  padding:1%;
}
.menuInner li:hover {
  background:gray;
}
.fixed {
  position:fixed;
  top:0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Space Filler</h2>
<h3>More Space Filler</h3>
<div id="menuLocator"></div>
<div class='horizontalMenu'>
  <div class="menuInner">
    <ul>
      <li>Menu 1</li>
      <li>Menu 2</li>
      <li>Menu 3</li>
    </ul>
  </div>
</div>
<div id="filler">
  <h4>Random Page Content</h4>
  <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 software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
<p>Bottom of Page</p>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我一直在努力解决同样的问题,感谢你的帖子,我能够找到帮助,我发现这种跳跃行为恰好发生在你所说的某些内容高度上,

它继续跳跃的原因是在标题停靠到顶部后的某个内容高度,pageYOffset读取返回意外值(我得到的值小于我预期的锚定偏移量,不知道为什么是这种情况发生在某种方式,错过了整个逻辑,因此菜单保持对接和解除对接导致闪烁的行为

我能够通过改变我的代码来传递它,以便在“#ribbonBarSection”/菜单已经停靠的情况下将菜单定位器偏移添加到滚动位置

1-我使用此方法返回我的菜单“#ribbonBarSection”是否应停靠在顶部或正常显示

hasPassedTopAnchor(hasBeenDocked: boolean): boolean {
    const anchor = document.getElementById('menuLocator');
    const scrollPosition = window.pageYOffset ;
    let adjusted = hasBeenDocked ? anchor.offsetTop : 0;
    return (scrollPosition + adjusted) > anchor.offsetTop;
  }

2-我在我的页脚之前添加了一个额外的div“#adjustedScrollHeight”。

3-当文档加载和@the window resize event

时,我从两个地方调用了以下自定义函数

自定义函数将改变div高度以添加额外的垂直滚动高度,从而减轻跳跃行为

  private onResize() {
    document.getElementById('adjustedScrollHeight').style.height = '0';
    this.adjustScrollHeight();
  }

  private adjustScrollHeight() {
    const verticalScrollDiff = document.documentElement.offsetHeight
      - document.documentElement.clientHeight;

    const anchorTop = document.getElementById('menuLocator').offsetTop;
    const ribbonBarOffsetTop = document.getElementById('ribbonBarSection').offsetTop;
    const upperScrollBoundary = ribbonBarOffsetTop + anchorTop + 1;

    if (verticalScrollDiff <= ribbonBarOffsetTop) {
      return;
    }

    if (verticalScrollDiff > upperScrollBoundary) {
      return;
    }

    //IE requires extra pixel for scrolling 
    const adjustedscrollHeight = ((upperScrollBoundary + 1) - verticalScrollDiff) + 1;
    document.getElementById('adjustedScrollHeight').style.height = adjustedscrollHeight + 'px';}

答案 2 :(得分:0)

我在我的情况下发现导致问题我的html就像

<nav>some content </nav>

我用div替换了nav标签,而且滚动工作正常!它必须与bootstrap事物有关,我假设nav标签期待一些未提供的css类