【问题标题】:Animate on scroll - animation buildups issue滚动动画 - 动画堆积问题
【发布时间】:2021-12-28 23:59:51
【问题描述】:

我有一个文本静态文本元素,当用户滚动超过 600 像素时会发生变化,当用户滚动超过 1400 像素时会再次发生变化

$(window).scroll(function () {
  if ($(this).scrollTop() > 600) {                    
    $('.p-circle').html('Text 1');
    $('.p-circle-s').html('Text 2');                     
  } 
});
$(window).scroll(function () {
  if ($(this).scrollTop() > 1400) { 
    $('.p-circle').html('Text 1 updated');     
    $('.p-circle-s').html('Text 2 updated');
  }
});

我怎样才能为它们制作一个基本的褪色动画,我尝试了下一个变体,但它们效果不佳(它会褪色 2 次)

if (scrollTop > 600 && scrollTop <= 1400) { 
    
  $('.p-circle').fadeOut(500, function() {
    $(this).text('Text 1').fadeIn(500);
  });
  $('.p-circle-s').fadeOut(500, function() {
    $(this).text('Text 2').fadeIn(500);
  });   
      
} else if (scrollTop > 1400 && scrollTop <= 2100) {

  $('.p-circle').fadeOut(500, function() {
    $(this).text('Text 1 updated').fadeIn(500);
  });
  $('.p-circle-s').fadeOut(500, function() {
    $(this).text('Text 2 Updated').fadeIn(500);
  }); 

}

【问题讨论】:

  • PS:你不需要用两个 $(window).scroll(function () {????
  • @RokoC.Buljan 他们这样做了,它在最后被锁住了。
  • @Travis 鹰眼。错过了
  • @RokoC.Buljan 很好地调用了两个 $(window).scroll 函数,我完全错过了。

标签: javascript jquery


【解决方案1】:

我认为你在正确的轨道上,但是你在最后一点的逻辑没有测试过渡是否已经发生。大致如下:

if ($(this).scrollTop() &gt; 600 &amp;&amp; $(this).scrollTop() &lt;= 1400 &amp;&amp; $(".p-circle").text() != 'Text 1')

我想我弄错了你的价值观,但这里有一个让你走上正轨的小提琴......

https://jsfiddle.net/64mj3k7n/3/

【讨论】:

  • 对不起,刚刚更新了那个小提琴链接,它是旧的。
  • 根据经验,您不需要检查文本,只需检查 scrollTop 值。相应地更改文本。
  • @RokoC.Buljan 我认为他们遇到的问题是,无论何时他们滚动,无论他们滚动到足以更改文本与否,它都会淡出并淡出。也许我错过了他们遇到的问题。
  • @RokoC.Buljan 虽然我不知道它属于哪里,但这听起来像是明智的建议。 jsfiddle.net/64mj3k7n/4 在链的开头有一个 .stop() ,这就是你的意思(杀死任何可能正在进行的动画)?这是一个不太令人满意的用户体验,意味着动画在滚动结束之前不会开始。你的意思是它属于其他地方吗?
  • Travis,我测试过,不,我创建了一个 OP 代码的演示,我认为你是对的。滚动事件触发太多次,.stop() 只是最初错误的错误方法:)
【解决方案2】:

更好的解决方案是创建一个函数(或类)Waypoints,使用如下:

Waypoints(window, [0, 100, 600, 1400], (wp) => {
  console.log(wp);   // {index:Int, value:Int}
});

接受三个参数:

  1. scroll-watchElement(或 String 选择器)
  2. 一个 Array 的滚动路径点值
  3. 一个回调函数

只有在滚动索引更改时才会触发回调 — 以防止每次滚动事件调用时累积。

/**
 * Waypoints
 * Trigger callbacks on a scrollY milestone 
 * @url https://stackoverflow.com/a/70520524/383904
 * @param {string|object} el String selector or Element object
 * @param {array} waypoints Array of px from lower to higher
 * @param {function} cb Callback function
 */

function Waypoints(el, waypoints = [0], cb) {
  el = (typeof el === "string") ? document.querySelector(el) : el;
  const wp = [...waypoints].reverse();
  const wpTot = wp.length;
  const getIndex = (n) => {
    const i = wp.findIndex(m => m <= n);
    return wpTot - 1 - (i < 0 ? wpTot : i);
  };
  let index = -1;
  const getTask = () => {
    const i = getIndex(el.scrollY);
    if (index === i) return; // No task to trigger
    index = i; // Update index
    const value = wp[wpTot - 1 - i]; // Get the waypoint name
    cb({ index, value }); // Trigger the callback
  };
  el.addEventListener("scroll", getTask);
  window.addEventListener("DOMContentLoaded", () => getTask);
  window.addEventListener("load", () => getTask);
  getTask();
}


/**
 * YOUR APP:
 */

const $circle1 = $('.p-circle');
const $circle2 = $('.p-circle-s');

const circle1txt = ["Text 1 scroll", "Text 1", "Text 1 updated"];
const circle2txt = ["Text 2 scroll", "Text 2", "Text 2 updated"];

Waypoints(window, [0, 600, 1400], (wp) => {
  $circle1.fadeOut(500, () => {
    $circle1.text(circle1txt[wp.index]).fadeIn(500);
  });
  $circle2.fadeOut(500, () => {
    $circle2.text(circle2txt[wp.index]).fadeIn(500);
  });
});
body { height: 3000px; } /* Just to force some scrollbars for this demo */
[class^="p-"] { position: fixed; }
.p-circle-s { top: 2rem; }
<div class="p-circle"></div>
<div class="p-circle-s"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

【讨论】:

  • 这是一个很酷的小功能,但我想知道有什么方法比在 if 中添加测试以查看是否需要更改文本更好?这是很多代码,我认为我无法分辨最终结果之间的区别......
  • @Travis 在 JS 逻辑中对任意文本进行硬编码从来都不是一个好主意。而且永远不会是一个:) 在您的示例中,您留下了太多if 语句和文本检查。容易出现错误并且它不是 DRY(不要重复自己)。
  • 我同意这一点,但该代码的复杂性对于这个应用程序来说似乎是多余的。我倾向于只为文本创建一些常量,但也许我高估了简单性。这是一个很酷的功能。
  • Travis,这并不过分。该函数按原样很小并且永远不会增长(除非您添加更多功能,例如在"20%""@0.5" 等分数中定义航点) - 但这是另一回事。现在,假设您再添加 100 个航路点,现在告诉我哪些代码会变得过分维护甚至编写所有不同的语句?
  • 是的,很公平。如果你有两个或三个以上的断点,我同意使用一个函数更有意义,而且这个函数工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
相关资源
最近更新 更多