【问题标题】:Fixed position on scroll flickering滚动闪烁的固定位置
【发布时间】:2019-01-23 15:36:57
【问题描述】:

我有一个带有headernav 的简单页面。在窗口滚动时,我将headernav 设置为fixed 位置。如果页面足够长可以滚动,一切顺利。如果页面处于某个高度,我会遇到闪烁的情况。

var prev = 0;
var $window = $(window);
var nav = $('.context-nav');
var $navbar = $('.navbar');

$(window).scroll(function(e) {
  var scrollTop = $window.scrollTop();
  nav.toggleClass('fixed', scrollTop >= prev);
  $navbar.toggleClass('fixed', scrollTop >= prev);
  prev = scrollTop;
});
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  text-decoration: none;
}

html,
body {
  font-size: 1rem;
  background-image: linear-gradient(to right, #8ca986, #789a71);
}

.sp {
  height: 700px;
}

header {
  position: relative;
  background: #fff;
  height: 80px;
  text-align: center;
  box-shadow: 0 1px 15px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
  transition: all 500ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 0s;
}

header.fixed {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
}

.page-container {
  padding: 2rem;
  position: relative;
  color: white;
}

.page-container .context-nav {
  display: flex;
  flex-direction: row;
  color: white;
  position: relative;
  margin-bottom: 3rem;
  padding: 1rem;
  transition: all 0.4s ease;
}

.page-container .context-nav.fixed {
  position: fixed;
  left: 0;
  right: 0;
  top: 60px;
  background-color: rgba(255, 255, 255, 0.08);
}

.page-container .context-nav .nav-item {
  padding: 20px;
  border: 1px solid white;
  margin-right: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="navbar">
  My header goes here
</header>
<div class="page-container">
  <div class="context-nav">
    <div class="nav-item">Item 1</div>
    <div class="nav-item">Item 2</div>
    <div class="nav-item">Item 3</div>
  </div>
  <h1 class="sp">Scroll me... </h1>
</div>

如果您将班级.sp 的高度调整为小尺寸,您可以看到问题。在我的示例中,我将其设置为 700px。当我尝试滚动时,它会设置类但直接将其删除,这会导致闪烁行为。当我将.sp 类高度设置为1200px 时,问题就不存在了。

有没有人想办法解决这个问题?

Codepen

【问题讨论】:

  • 以后请在问题中使用所有相关代码。在这种情况下,我已经为您完成了

标签: jquery css scroll fixed


【解决方案1】:

发生闪烁是因为当您将元素设置为固定位置时,它会超出流程并改变偏移量,如果您要查找的是在滚动时显示stickyElements,我建议您克隆您的元素想要在固定容器中显示为粘性然后显示该容器,这样原始元素将保持在其原始位置并且不会导致内容跳转,我还注意到您正在使用计数器来显示和隐藏粘性元素,我除非你有不同的想法,否则思考是低效的。

这是我快速从您的代码中分出的代码笔,以说明我的意思:

var $window = $(window);
var $stickyHeader = $('.stickyHeader');
var $nav = $('.context-nav');
var navOffset = $nav.offset().top;
var $navbar = $('.navbar');
var $newNavBar = $navbar.clone();
var $newNav = $nav.clone();

$stickyHeader.append($newNavBar);
$stickyHeader.append($newNav);
var timer;

$(window).scroll(function (e) {
	if(timer) {
		window.clearTimeout(timer);
	}

	timer = window.setTimeout(function(){
		if($window.scrollTop() > navOffset) {
			$stickyHeader.addClass('active');
		}
		else {	
			$stickyHeader.removeClass('active');
		}
	}, 100);
});
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  text-decoration: none;
}

html,
body {
  font-size: 1rem;
  background-image: linear-gradient(to right, #8ca986, #789a71);
}

.sp {
  height: 700px;
}

header {
  position: relative;
  background: #fff;
  height: 80px;
  text-align: center;
  box-shadow: 0 1px 15px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
}
.active header {
  width: 100%;
  height: 60px;
}

.page-container {
  padding: 2rem;
  position: relative;
  color: white;
}

.context-nav {
  display: flex;
  flex-direction: row;
  color: white;
  position: relative;
  margin-bottom: 3rem;
  padding: 1rem;
}
.active .context-nav {
  left: 0;
  right: 0;
  background-color: rgba(255, 255, 255, 0.08);
}
.context-nav .nav-item {
  padding: 20px;
  border: 1px solid white;
  margin-right: 1rem;
}

.stickyHeader {
  width: 100%;
  position: fixed;
  height: 0;
  overflow: hidden;
  top: -140px;
  transition: height 200ms ease, top 200ms ease;
}
.stickyHeader.active {
  height: 140px;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="stickyHeader">
	
</div>
<header class="navbar">
	My header goes here
</header>
<div class="page-container">	
	<div class="context-nav">
		<div class="nav-item">Item 1</div>
		<div class="nav-item">Item 2</div>
		<div class="nav-item">Item 3</div>
	</div>
	<h1 class="sp">Scroll me... </h1>
</div>

https://codepen.io/j-lastforone/pen/bzddmK

【讨论】:

  • 嗨,桑,感谢您的回复。克隆使它变得更复杂一些,因为导航栏,尤其是上下文导航包含的元素在用户单击表格行时附加了不同的 js 事件。克隆时,我必须重新附加所有这些事件等,这使得代码复杂且更难以维护。此外,当页面足够长可以滚动时,我完全没有问题。闪烁仅在页面高度处于特定高度时发生。你肯定帮我换了个方向。谢谢你
  • 没问题,$.clone() 也允许您复制事件,实际上它甚至允许您进行深度复制,这取决于您如何使用它。 api.jquery.com/clone 并了解问题尝试在事件处理程序中控制台记录 prev 的值,你会明白我的意思。
  • 我知道复制和深复制。那不是问题。上下文导航 get 被激活,并且在网格内的行单击时设置值。上下文导航也第一次从动作中呈现在剃刀视图中。之后,ajax 将更新上下文菜单等。如果我克隆,我必须维护两个副本等,这将导致 spaggetti 代码
猜你喜欢
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 2013-08-13
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 2010-11-17
相关资源
最近更新 更多