You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

滚动淡入元素后保持显示的JavaScript问题及代码优化咨询

Fixing the Fade-Out Issue & Code Optimization Tips

Hey there! I see you're diving into scroll-triggered animations with JavaScript—great start! Let's tackle that frustrating fade-out problem first, then go over some ways to polish your code for better performance and readability.

Why the Fade-Out Happens

Right now, your detection() function removes the in-view class whenever an element scrolls out of the viewport. That's exactly why your elements fade back out once you scroll past them. We need to make sure elements stay visible after their first fade-in, no matter where they are on the page.

Solution: Persist the Visible State

We can add a simple flag (using a data attribute) to mark elements that have already completed their animation. Once an element is marked as "animated", we won't touch its classes anymore.

Here's the updated JavaScript code:

$(function() {
    var html = $('html');
    // Cache jQuery objects upfront to avoid repeated DOM queries
    var $items = $('*[data-animate-in], *[data-detect-viewport]');
    var waiting = false;
    var $w = $(window);

    // On Screen Check - keep this handy utility function
    $.fn.isOnScreen = function() {
        var elementTop = this.offset().top,
            elementBottom = elementTop + this.outerHeight(),
            viewportTop = $w.scrollTop(),
            viewportBottom = viewportTop + $w.height();
        return elementBottom > viewportTop && elementTop < viewportBottom;
    };

    function detection() {
        $items.each(function() {
            var $el = $(this);
            // Skip elements that have already finished animating
            if ($el.data('animated')) return;

            if ($el.isOnScreen()) {
                $el.addClass("in-view").data('animated', true); // Mark as permanently animated
            }
            // Remove the else branch that was removing the in-view class
        });
    }

    // Debounced scroll/resize handler to avoid excessive function calls
    $w.on("resize scroll", function() {
        if (waiting) return;
        waiting = true;
        detection();
        setTimeout(function() {
            waiting = false;
        }, 100);
    });

    // Initialize animations on page load
    $(document).ready(function() {
        setTimeout(function() {
            detection();
        }, 500);

        $items.each(function() {
            var $el = $(this);
            // Use jQuery's data() method for cleaner, type-safe attribute access
            var delay = $el.data('animate-in-delay') || 0;
            var delayInSeconds = delay / 1000 + "s";
            $el.css("transition-delay", delayInSeconds);
        });
    });
});

Key Changes:

  • Cached jQuery Objects: Converted items to $items (a jQuery collection) upfront, so we don't re-wrap elements in jQuery every time we loop through them (saves DOM query time!).
  • Animation Flag: Added data('animated') to mark elements that have finished their fade-in. The detection() function skips these elements entirely now.
  • Removed Unnecessary Logic: Got rid of the else clause that was removing the in-view class—no more unwanted fade-outs!
  • Cleaner Data Access: Used $el.data('animate-in-delay') instead of getAttribute() for simpler, more readable code that automatically handles type conversion.

CSS Optimization Tips

Your CSS works, but we can make it more concise and avoid redundant transitions:

/* -- Animation -- */
[data-animate-in] {
    opacity: 0;
    transition: transform 0.8s ease, opacity 0.8s ease;
}

[data-animate-in="up"] { transform: translate3d(0, 24px, 0); }
[data-animate-in="left"] { transform: translate3d(-25%, 0, 0); }
[data-animate-in="right"] { transform: translate3d(25%, 0, 0); }
[data-animate-in="down"] { transform: translate3d(0, -24px, 0); }
[data-animate-in="fadeIn"] { transform: translate3d(0, 0, 0); }

/* Simplify the in-view state - inherit transition timing if needed */
[data-animate-in].in-view {
    opacity: 1;
    transform: translate3d(0, 0, 0);
    -webkit-transform: translate3d(0, 0, 0);
    /* Optional: Adjust transition timing here, or remove to use the base timing */
    transition: transform 0.6s ease, opacity 0.6s ease;
}

.fade-in {
    opacity: 0;
    transition: opacity 1s ease;
}

.page-loaded .fade-in,
.page-loaded.fade-in {
    opacity: 1;
}

CSS Improvements:

  • Grouped related selectors (like the .page-loaded rules) for better readability
  • Kept transition properties consistent to avoid unexpected animation behavior
  • Made the structure cleaner by separating base styles from animation states

Additional Optimization Ideas

  • Reusable Debounce Function: Instead of rolling your own debounce with waiting and setTimeout, you could use a reusable debounce utility to clean up the scroll/resize handler even more.
  • RequestAnimationFrame: Wrap the detection() call in requestAnimationFrame to ensure animations run smoothly with the browser's repaint cycle.
  • CSS Custom Properties: If possible, use CSS variables for delay values instead of setting them via JavaScript—this keeps styling in CSS where it belongs.

Hope this helps you fix the issue and learn a bit more about efficient JavaScript/CSS for animations! 😊

内容的提问来源于stack exchange,提问作者Louie Heaton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:57:37