【问题标题】:jQuery fade out when scrolling: element flickers on viewport border滚动时jQuery淡出:视口边框上的元素闪烁
【发布时间】:2019-07-07 16:07:57
【问题描述】:

我有这个代码:

.fade 元素的 opacity=0。我在元素到达视口时添加“可见”类,并在离开后删除该类。到目前为止一切正常,但元素在到达视口上边界时显示出奇怪的闪烁:它们消失了,又回来又消失,就好像它们不确定它们是在视口上还是在视口外。这是我的 jQuery 和 CSS:

	$(window).scroll(function() {
		var tags = $(".fade");
		for (var i = 0; i < tags.length; i++) {
			var tag = tags[i];
			if(isScrolledIntoView($(tag))){
				$(tag).addClass("visible");
			}
			else {
				$(tag).removeClass("visible");
			}
		}
	});
	function isScrolledIntoView(elem){
		var $elem = $(elem);
		var $window = $(window);
		var docViewTop = $window.scrollTop();
		var docViewBottom = docViewTop + $window.height();
		var elemTop = $elem.offset().top;
		var elemBottom = elemTop + $elem.height();
		return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
	}
.panel { 
  height: 500px; 
  position: relative;
  color: white;
}

.p1 { background: red; }
.p2 { background: green; }
.p3 { background: orange; }
.p4 { background: green; }

.fade {
  background: black;
  color: white;
  position: absolute;
  max-width: 500px;
  padding: 2.0rem;
  opacity: 0;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, 0); 
}

.fade.visible {
  opacity: 1;
  transition: all 1.0s;
  transform: translate(-50%, -50%); 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='panel p1'>
<div class='fade'>Content Fade 1</div>
</div>

<div class='panel p2'>
<div class='fade'>Content Fade 2</div>
</div>

<div class='panel p3'>
<div class='fade'>Content Fade 3</div>
</div>

<div class='panel p4'>
<div class='fade'>Content Fade 4</div>
</div>

滚动速度越慢,问题就越明显。我宁愿在元素完全超出视口之前删除该类,甚至可能加上一点额外的空间。

任何可以帮助我击败这个棘手的小恶魔的提示都非常受欢迎。

谢谢 拉尔夫

【问题讨论】:

  • 请不要将您的可执行代码发布到第三方网站,因为这些链接可能会随着时间的推移而失效。只需将代码放入代码 sn-p 中,就在这里。另外,不要将可执行代码的“部分”放入代码 sn-p 中,以使该部分不再可执行。代码 sn-ps 是用来运行代码的。如果你只是想显示一些代码,不要把它放在 sn-p 中。
  • 在 Windows 10 上的 Chrome 74 中运行时,我没有遇到您描述的问题。
  • 啊,好的,非常感谢。我不知道该怎么做,你为我编辑的绝对没问题。
  • 我目前没有 Windows 机器,但问题在 MacOs Firefox、Chrome 和 Safari 上都以完全相同的方式出现。

标签: javascript jquery scroll


【解决方案1】:

编辑:- 我添加了代码 sn-p 来正确执行此操作。您已经实现了大部分目标,只是留下了一个小错误,您看到您无法观察到元素移出视口并将其移回有点违背了目的,您可以做的是放置另一个 div 作为占位符您试图隐藏/显示并观察该 div 的默认可见位置。 sn-p 和它的代码会告诉你。

P.S :- 如果你经常注意到观察这个词,请尝试查看交叉点观察器来实现这种功能,而无需进行所有这些容易出错的计算。它们不是 100% 兼容浏览器的,只是看看你的观众,sn-p 提供的作品也有效,我已经对其进行了测试。

$(window).scroll(function() {
    var tags = $(".fade");
    for (var i = 0; i < tags.length; i++) {
        var tag = tags[i];
        if(isScrolledIntoView($(tag).siblings(".fade-check"))){
            $(tag).addClass("visible");
        }
        else {
            $(tag).removeClass("visible");
        }
    }
});
function isScrolledIntoView(elem){
    var $elem = $(elem);
    var $window = $(window);
    var docViewTop = $window.scrollTop();
    var docViewBottom = docViewTop + $window.height();
    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();
    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
.panel { 
    height: 500px; 
    position: relative;
    color: white;
}

.p1 { background: red; }
.p2 { background: green; }
.p3 { background: orange; }
.p4 { background: green; }

.fade {
    background: black;
    color: white;
    max-width: 500px;
    padding: 2.0rem;
    opacity: 0;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, 0); 
    transition: all 1.0s;
}
.fade-check {
    padding: 2.0rem;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    height: 1rem;
}
.fade.visible {
    opacity: 1;
    transform: translate(-50%, -50%);
}
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class='panel p1'>
        <div class='fade-check'></div>
        <div class='fade'>Content Fade 1</div>
    </div>

    <div class='panel p2'>
        <div class='fade-check'></div>
        <div class='fade'>Content Fade 2</div>
    </div>

    <div class='panel p3'>
        <div class='fade-check'></div>
        <div class='fade'>Content Fade 3</div>
    </div>

    <div class='panel p4'>
        <div class='fade-check'></div>
        <div class='fade'>Content Fade 4</div>
    </div>
</body>

这是发生的,因为您依赖 .fade 元素的偏移值来确定它们是否向上滚动以及是否向上滚动。您正在对它们应用 translate ,这正在改变偏移结果,这就是为什么您会获得这种摆动效果,只需从 fade.visible 元素中删除 translate: transform(-50%, -50%) 并将过渡移动到 .fade 类中,您将获得淡入淡出实际上是你想要的。

【讨论】:

  • 感谢 Himanshu,我尝试了您的建议,现在它发生了我所怀疑的:摇摆消失了,但不幸的是 .fade 元素不再移动,只是逐渐消失。也许我说得不够清楚:我希望它们有两个过渡——淡入和稍微移动到以 .panel 为中心的最终位置。我并不惊讶这个问题与偏移量有关,但是我怎样才能实现同时运行两个转换呢?还是不可能?
  • 我很抱歉拉尔夫。我知道你只是想把它们从帖子的标题中淡出。我已经更新了答案并包含了 sn-p 来做你所要求的。请让我知道这是否解决了您的问题,如果它解决了您的问题,请考虑确认答案,并查看交叉点观察者 api,现在还有一个可用的 polyfill。
  • 完美完成,Himanshu,一百万谢谢!也没有理由道歉——是我没有把我的计划说清楚。
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多