【问题标题】:jQuery fadeTo calls not functioning as expected when called by scroll()当滚动()调用时,jQuery fadeTo 调用未按预期运行
【发布时间】:2021-12-23 09:09:39
【问题描述】:

我一直在学习 Ruby on Rails 和 Javascript,并尝试学习在进行过程中制作动画。

我有一系列由 Articles 控制器生成的引导卡片,并在索引视图中通过文章部分显示,其中卡片列表(代表帖子/消息)沿着页面向下移动。我希望这些卡片在滚动时淡入视野。

我用css从0开始卡片不透明度:

$bg_color: #23282e;
$corner_radius: 5px;

.card {
  border-radius: $corner_radius;
  opacity: 0;
}

并使用 javascript 将其淡化为 1:

function fadeCardsIn() {
    const window_top = $(window).scrollTop()
    const window_bottom = $(window).scrollTop() + $(window).innerHeight()

    console.log(`Viewport: ${window_top} to ${window_bottom}.`)

    const cards = $(".card")
    let count = 0

    cards.each(function() {
        count += 1
        const card = $(this)

        const card_top = card.offset().top;
        const card_bottom = card.offset().top + card.outerHeight()

        // If our card is in the range of the window viewport.
        if ((window_bottom > card_top) && (window_top < card_bottom)) {
            card.fadeTo(1000, 1, "swing")
            console.log(`Showing card ${count}.`)
        } else {
            card.fadeTo(1000, 0, "swing")
        }
    })
}

$(document).ready(fadeCardsIn)
$(window).scroll(fadeCardsIn)

我已经采取了应该允许事情在没有所有 Rails 后端和没有部分的情况下运行的位,在 html 中复制/粘贴了几张卡以模拟我在渲染视图中使用的内容:
https://jsfiddle.net/n9kemt3L/5/

加载时,javascript 函数按预期工作,视口中的前几张卡片淡入。但是在滚动时,根据控制台日志,正确的卡片正在“显示”并且应该是动画/淡入,但它们要么从不淡入,要么淡入/淡出非常晚(有时在不滚动后超过 30 秒以上)。

我假设通过滚动在同一张卡片上多次调用fadeTo函数会导致问题,可能在第一个fadeTo完成之前多次调用fadeTo,但我不确定。

我应该如何着手解决这个问题?非常欢迎任何能将我推向正确方向的建议。

如果 fadeTo 过多的调用破坏了动画,那么我想我可能需要添加某种状态来了解每张卡片何时被动画进/出,但我不知道应该从哪里开始如果是这样的话,因为每张卡片都是由 rails 生成并通过分页提供的,我只是在最终使用 jQuery 的 each() 函数渲染时迭代每张卡片。

另一方面,在这个设置中,我根本无法让 fadeIn 和 fadeOut 发挥作用,因此我改用了 fadeTo。

除了在滚动上调用这种函数之外,还有更好的方法吗?


编辑:我设法通过简单地删除 else 语句来获得我想要的功能。

    cards.each(function() {
        count += 1
        const card = $(this)

        const card_top = card.offset().top;
        const card_bottom = card.offset().top + card.outerHeight()

        // If our card is in the range of the window viewport.
        if ((window_bottom > card_top) && (window_top < card_bottom)) {
            console.log(`Showing card ${count}.`)
            card.fadeTo(500, 1, "swing",function(){console.log(`Loaded card ${count}`)})

但我仍然想知道是否有更好的方法来做到这一点,因为每次滚动时每个循环都会触发。

【问题讨论】:

    标签: javascript jquery ruby-on-rails sass


    【解决方案1】:

    绝对感觉自己走在正确的道路上。

    当我让事物从顶部、底部、左侧或右侧淡入时,我通常不会明确地在它们自己的类中将初始不透明度设为 0。

    我创建了一个初始不透明度为 0 的动画类,然后将其分配给它们。

    就这样……

    HTML

    <div class='card'>im a card example </div>
    

    CSS

    .card {
    
    }
    
      @keyframes fromRight {
        0% {
          transform: translateX(50px);
          opacity: 0;
        }
        100% {
          transform: translateX(0);
          opacity: 1;
        }
      }
    

    Javascript/jQuery

    $(document).ready(function() {
        $(window).scroll(function() {
            let position = $(this).scrollTop();
            console.log(position)
    
            // specify your position by inspecting the page
            if (position >= 1100) {
                $('.card').addClass('fromRight');
            }
        });
    })
    

    【讨论】:

    • 这是一个非常酷的想法,尽管在加载/滚动时成功添加了类,但我无法让 css 正确设置动画。不过,我确实设法解决了至少一半的问题。只需删除重新隐藏事物的 else 语句/逻辑,现在动画按预期触发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多