向下滚动时淡入,向上滚动时淡出 - 基于窗口中的元素位置

IT技术 javascript jquery scroll fade
2021-01-27 22:41:51

当它们在窗口中完全可见时,我试图让一系列元素在向下滚动时淡入。如果我继续向下滚动,我不希望它们淡出,但是如果我向上滚动,我确实希望它们淡出。

这是我找到的最接近的 jsfiddle。 http://jsfiddle.net/tcloninger/e5qaD/

$(document).ready(function() {

/* Every time the window is scrolled ... */
$(window).scroll( function(){

    /* Check the location of each desired element */
    $('.hideme').each( function(i){

        var bottom_of_object = $(this).position().top + $(this).outerHeight();
        var bottom_of_window = $(window).scrollTop() + $(window).height();

        /* If the object is completely visible in the window, fade it it */
        if( bottom_of_window > bottom_of_object ){

            $(this).animate({'opacity':'1'},500);

        }    
    }); 
}); 
});

它在向下滚动时完全符合我的要求,但我也希望元素在我向上滚动时淡出它们。

我没有运气就试过这个。

            if( bottom_of_window > bottom_of_object ){

                $(this).animate({'opacity':'1'},500);  

            } else {

               $(this).animate({'opacity':'0'},500); }

非常感谢您花时间看这个。

4个回答

您的尝试无效的原因是因为两个动画(淡入和淡出)相互对抗。

就在对象变得可见之前,它仍然不可见,因此淡出动画会运行。然后,在同一对象变得可见的几分之一秒后,淡入动画将尝试运行,但淡出仍在运行。所以他们会互相对抗,你什么也看不到。

最终对象会变得可见(大部分时间),但这需要一段时间。如果您使用滚动条按钮上的箭头按钮向下滚动,动画就会起作用,因为您将使用更大的增量滚动,从而减少滚动事件。


解释够了,解决方案(JS、CSS、HTML):

$(window).on("load",function() {
  $(window).scroll(function() {
    var windowBottom = $(this).scrollTop() + $(this).innerHeight();
    $(".fade").each(function() {
      /* Check the location of each desired element */
      var objectBottom = $(this).offset().top + $(this).outerHeight();
      
      /* If the element is completely within bounds of the window, fade it in */
      if (objectBottom < windowBottom) { //object comes into view (scrolling down)
        if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
      } else { //object goes out of view (scrolling up)
        if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
      }
    });
  }).scroll(); //invoke scroll-handler on page-load
});
.fade {
  margin: 50px;
  padding: 50px;
  background-color: lightgreen;
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div>
  <div class="fade">Fade In 01</div>
  <div class="fade">Fade In 02</div>
  <div class="fade">Fade In 03</div>
  <div class="fade">Fade In 04</div>
  <div class="fade">Fade In 05</div>
  <div class="fade">Fade In 06</div>
  <div class="fade">Fade In 07</div>
  <div class="fade">Fade In 08</div>
  <div class="fade">Fade In 09</div>
  <div class="fade">Fade In 10</div>
</div>
小提琴:http : //jsfiddle.net/eLwex993/2/

  • 我裹着淡入代码行的如果子句中:if ($(this).css("opacity")==0) {...}这可确保对象仅在opacityis时淡入0淡出也一样。这可以防止淡入和淡出相互影响,因为现在在一个对象上只同时运行两者之一。
  • 我换.animate().fadeTo()它是 jQuery 的不透明度专用函数,编写起来要短得多,而且可能比动画更轻。
  • 我换.position().offset()这总是相对于身体计算,而位置是相对于父级的。对于你的情况,我相信抵消是要走的路。
  • 我换$(window).height()$(window).innerHeight()根据我的经验,后者更可靠。
  • 直接在滚动处理程序之后,我在页面加载时调用该处理程序一次$(window).scroll();现在您可以为页面上所有需要的对象提供.fade类,并且在页面加载时不可见的对象将立即淡出。
  • #container从 HTML 和 CSS 中删除,因为(至少对于这个答案)它不是必需的。(我想也许您需要 ,height:2000px因为您使用了.position()而不是.offset(),否则我不知道。当然可以将它留在您的代码中。)

更新

如果你想比其他的不透明度值01,使用下面的代码:

(小提琴:http : //jsfiddle.net/eLwex993/3/

  • 我在 if 子句中添加了一个阈值,请参阅下面的说明
  • 我在函数开始时为 thethreshold和 for创建了变量min/max在函数的其余部分,这些变量被引用。这样,如果您想再次更改这些值,只需在一个地方进行。
  • 我还添加|| pageLoad了 if 子句。这对于确保所有对象在页面加载时淡化到正确的不透明度是必要的。pageLoad是一个布尔值,在fade()调用时作为参数发送
    我必须将淡入淡出代码放在 extra 中function fade() {...},以便在pageLoad调用滚动处理程序时能够沿布尔值发送
    我没有看到任何其他方法可以做到这一点,如果有人这样做,请发表评论。

说明:您的小提琴中
的代码不起作用的原因是因为实际的不透明度值总是与您设置的值略有偏差。因此,如果您将不透明度设置为,则实际值(在本例中)为这只是您必须通过跟踪和错误学习的那些小错误之一。这就是为什么这个if子句将无法正常工作:0.30.300000011920929if ($(this).css("opacity") == 0.3) {...}

我添加了一个阈值,以将这种差异考虑在内:== 0.3成为<= 0.31.
(我已将阈值设置为0.01,当然可以更改,只要实际不透明度介于设置值和此阈值之间即可。)

运算符现在从 更改==<=>=


更新 2:

如果要根据元素的可见百分比淡化元素,请使用以下代码:

(小提琴:http : //jsfiddle.net/eLwex993/5/

@sm.ali 可能有两件事阻止您的代码工作。1)一定要给你的页脚fade类,这段代码只适用于具有该类的元素。2)改变if (objectBottom < windowBottom) {if (objectBottom <= windowBottom) {; 因为您的页脚(可能)粘在页面底部,所以页脚底部永远不会小于窗口底部。通过更改<<=,当页脚底部等于窗口底部时,代码也将起作用。或者,您可以使用它objectTop来创造更好的效果,我会留给您。
2021-03-15 22:41:51
这是在页脚上工作吗?我试过了,这很好用,但不是在页脚上
2021-04-01 22:41:51
@CamrinParnell - 我想我会将行的每个元素(的 ID)放入一个数组中,然后在 for 循环中遍历该数组中的fadeTo()每个元素,在每个元素上使用该行,但淡入淡出更短 -期间。
2021-04-03 22:41:51
@minimographite - 我为除0之外的其他不透明度值添加了更新1感谢您的赞赏,这总是使海报快乐!
2021-04-10 22:41:51
这将如何修改,以便您可以在每行中的每个元素从左到右 1 乘 1 淡化,而不是在该行可见时同时淡化整行?
2021-04-11 22:41:51

我稍微调整了您的代码,使其更加健壮。在渐进增强方面,在 JavaScript 中拥有所有淡入淡出逻辑可能会更好。在 myfunksyde 的示例中,任何没有 JavaScript 的用户都看不到任何东西,因为opacity: 0;.

    $(window).on("load",function() {
    function fade() {
        var animation_height = $(window).innerHeight() * 0.25;
        var ratio = Math.round( (1 / animation_height) * 10000 ) / 10000;

        $('.fade').each(function() {

            var objectTop = $(this).offset().top;
            var windowBottom = $(window).scrollTop() + $(window).innerHeight();

            if ( objectTop < windowBottom ) {
                if ( objectTop < windowBottom - animation_height ) {
                    $(this).html( 'fully visible' );
                    $(this).css( {
                        transition: 'opacity 0.1s linear',
                        opacity: 1
                    } );

                } else {
                    $(this).html( 'fading in/out' );
                    $(this).css( {
                        transition: 'opacity 0.25s linear',
                        opacity: (windowBottom - objectTop) * ratio
                    } );
                }
            } else {
                $(this).html( 'not visible' );
                $(this).css( 'opacity', 0 );
            }
        });
    }
    $('.fade').css( 'opacity', 0 );
    fade();
    $(window).scroll(function() {fade();});
});

在这里看到它:http : //jsfiddle.net/78xjLnu1/16/

干杯,马丁

很好地了解非 JavaScript 用户。我很喜欢你的回答:)
2021-04-06 22:41:51

我知道已经晚了,但我采用了原始代码并更改了一些内容以轻松控制 css。所以我用 addClass() 和 removeClass() 做了一个代码

这里的完整代码:http : //jsfiddle.net/e5qaD/4837/

        if( bottom_of_window > bottom_of_object ){
            $(this).addClass('showme');
       }
        if( bottom_of_window < bottom_of_object ){
            $(this).removeClass('showme');
我喜欢这个选项更好用!!如何更改bottom_of_object 使其位于底部的顶部?
2021-03-25 22:41:51
很少的代码和完美的作品。我在我的投资组合网站上添加了淡入淡出元素。好吧,如果您使用过渡属性在滚动时平滑淡入效果会更好。
2021-04-02 22:41:51

对不起,这是旧线程,但我想有些人仍然需要这个,

注意:我使用 Animate.css 库来实现淡入淡出动画。

我使用了您的代码并刚刚添加了 .hidden 类(使用引导程序的隐藏类)但您仍然可以定义 .hidden { opacity: 0; }

$(document).ready(function() {

/* Every time the window is scrolled ... */

$(window).scroll( function(){

/* Check the location of each desired element */
$('.hideme').each( function(i){

    var bottom_of_object = $(this).position().top + $(this).outerHeight();
    var bottom_of_window = $(window).scrollTop() + $(window).height();


    /* If the object is completely visible in the window, fade it it */
    if( bottom_of_window > bottom_of_object ){

        $(this).removeClass('hidden');
        $(this).addClass('animated fadeInUp');
    }    else {
            $(this).addClass('hidden');
               }

}); 
}); 
});

另一个注意事项:将此应用于容器可能会导致它出现故障。