首页 > 解决方案 > 滚动时jQuery淡出:视口边框上的元素闪烁

问题描述

我有这个代码:

.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>

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

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

谢谢拉尔夫

标签: javascriptjqueryscroll

解决方案


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

PS :- 如果您经常注意到观察词,请尝试查看交叉点观察器以实现这种功能,而无需进行所有这些容易出错的计算。它们不是 100% 兼容浏览器的,只是看看你的观众,提供的片段也有效,我已经测试过了。

$(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 ,这正在改变偏移结果,这就是为什么您会获得这种摆动效果,只需translate: transform(-50%, -50%)从 fade.visible 元素中删除 并将过渡移动到 .fade 类中,您将获得淡入效果欲望。


推荐阅读