【问题标题】:Fade elements as they reach the top of the page?当元素到达页面顶部时淡化元素?
【发布时间】:2017-03-22 10:43:55
【问题描述】:

所以我像这样使用 jQuery 脚本;

$(window).scroll(function(){
    $(".element").css("opacity", 1 - $(window).scrollTop() / 700);
  });

在滚动到页面顶部时隐藏绝对定位的弹性框元素。我想在页面下方应用相同的规则集的其他内容;我希望它们在页面底部可见时保持 100% 的不透明度,然后在用户滚动时让它们淡出,但这似乎只适用于最初显示在窗口中的第一个元素。我不知道为什么会这样——我玩过700 值,但对于页面下方的元素来说,它似乎永远不准确。

Here's a jsfiddle

我正在处理的内容是文本和图像。我认为这可能无法以我希望的方式实现 - 如果我可以让它工作,理想情况下一个文本块会从顶部到底部而不是整个元素一次淡出,但我明白用这种方法可能是不可能的。

【问题讨论】:

  • 不用除/700,你可以除以元素的偏移量,像这样:$(".textblock").css("opacity", 1 - $(window).scrollTop( ) / $(".textblock").offset().top);
  • 那是因为 scrollTop 仅基于视口本身,而您的元素位于代码的各个部分。您必须遍历每个元素,并从视口顶部检查其相对位置,然后决定是否淡化它(或淡化程度)。

标签: javascript jquery html css scrolltop


【解决方案1】:

我建议您为所有想要淡化行为的元素使用一个通用类。您也可以使用选择器的组合。您的实现的主要问题是您只能监听视口的滚动位置,而忽略页面上的不同元素与文档顶部的垂直距离不同的事实。 您将不得不计算元素相对于视口顶部的位置

因此,要做到这一点,您必须:

  1. 遍历您希望在滚动时淡出的每个元素
  2. 计算其相对于视口顶部的垂直偏移(基本上是元素的顶部偏移位置减去当前滚动位置)
  3. 如果此偏移超过某个阈值(可以是像素值或视口高度的百分比),则开始计算淡入淡出

在下面的概念验证示例中,我有:

  • 对所有要褪色的项目应用一个公共类
  • 添加了基本设置,以便仅当元素超过视口的一半时才开始淡出(视口的上半部分可以视为“淡入淡出区域”)
  • 不透明度值与“淡入淡出区域”内元素位置之间的线性插值

$(window).scroll(function() {
  // Setting: Start fading halfway up the page
  var startPos = 0.5;

  // Cache window object
  var $w = $(window);

  // Basically, we go through each element and check its relative position within the viewport
  $('.scrollFade').each(function() {

    // Get current relative position in viewport, based on the top edge
    var pos = $(this).offset().top - $w.scrollTop();

    // Get viewport height
    var vh = $w.height();

    if (pos < vh * startPos) {
      // If element has past the starting threshold, we fade it
      $(this).css('opacity', pos / (vh * startPos) * 1);
    } else {
      $(this).css('opacity', 1);
    }
  });
});
.textblock {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  bottom: 0px;
}

.extratext {
  margin-top: 500px;
}

div {
  height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <p class="textblock scrollFade">
    hey hey hey!
  </p>
</div>

<div>
  <p class="extratext scrollFade">
    Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up
    one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum
    et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section
    1.10.32.
  </p>
</div>

【讨论】:

  • 这是一个非常棒的解决方案。我什至没有想过从顶部计算价值。做得很好,谢谢你的帮助
【解决方案2】:

我会这样做:

.topGradient{
    height: 100px;
    width: 100%;
    background:linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));
    position: fixed;
    top:0;
    z-index: 100;
}


.bottomGradient{
    height: 100px;
    width: 100%;
background:linear-gradient(to top, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));   position: fixed;
    bottom:0;
    z-index: 100;
}

Here is the JSFiddle demo

我所做的是创建 2 个 div 并将它们放置在窗口的顶部和底部。然后我使用 z-index 将它们设置在所有其他元素之上,然后给它们一个具有透明度的渐变,从而为您提供您提到的元素的淡入/淡出效果。

【讨论】:

  • 我真的很喜欢这个解决方案,我实际上试图实现这样的东西,但是我在这个网站的背景中有一个固定定位的全屏视频,所以我宁愿不显示渐变非文本元素的顶部。如果有办法操纵 z-index 或伪元素以使其成为可能,那将是完美的,但我认为没有
【解决方案3】:

您需要获取页面上的元素位置并将其用作淡入淡出开始时的偏移量。 Here is an updated fiddle.

$(window).scroll(function(){
    $(".textblock").css("opacity", 1 - $(window).scrollTop() / 700);
    var offsetTop = $(".extratext").offset().top;
    $(".extratext").css("opacity", 1 - ($(window).scrollTop() - offsetTop) / 700);
  });

【讨论】:

    【解决方案4】:
    fadeAtTop(el) {
        const startPos = 0.25;
        const $window = $(window);
        const viewportHeight = $window.height();
    
        el.toArray().forEach(el => {
          const $el = $(el);
          let position = $el.offset().top - $window.scrollTop();
          let opacity = position < viewportHeight * startPos ? position / (viewportHeight * startPos) * 1 : 1;
    
          $el.css('opacity', opacity);
        });
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-14
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2020-06-13
      相关资源
      最近更新 更多