基于jQuery的堆叠卡片动画:序列动画问题排查与优化
Looks like you're running into a common issue when scaling hard-coded UI logic—your original code was tied directly to 3 inactive cards, so adding more steps breaks the step-to-card mapping. Let's fix this by making the logic dynamic instead of hard-coding everything:
核心思路
Instead of relying on first(), last(), or hard-coded variables like inactive1/inactive2, we'll track the current step index and dynamically target the corresponding inactive cards. This way, the code works for any number of steps you add later.
Step 1: Update HTML for Flexibility
First, rename your inactive card classes to a generic name (like inactive-card) so we can select all of them at once. Keep the inline styles for initial margins/heights:
<div id="section2play"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div class="row"> <div class="col-sm-12"> <div class="inner-container"> <!-- Generic class for all inactive cards --> <div class="card inactive-card" style="height: 8px; margin-left: 30px; margin-right: 30px;"></div> <div class="card inactive-card" style="height: 8px; margin-left: 20px; margin-right: 20px;"></div> <div class="card inactive-card" style="height: 8px; margin-left: 10px; margin-right: 10px;"></div> <div class="card"> <div class="content active" style="opacity: 1; right: 10%;"> <h1>Step 1</h1> <p>Make perfectly hot homemade coffee. Carefully pour into coffee cup. <i class="em em-coffee"></i></p> <a class="button" href="#">Next step →</a> </div> <div class="content"> <h1>Step 2</h1> <p>Trip. Spill all over the place.</p> <a class="button" href="#">Next step →</a> </div> <div class="content"> <h1>Step 3</h1> <p>Repeat.</p> <a class="button" href="#">Next step →</a> </div> <div class="content"> <h1>Step 4</h1> <p>Repeat.</p> <a class="button" href="#">Next step →</a> </div> </div> </div> </div> </div> </div> </div> </div> </div>
Step 2: Rewrite JavaScript Logic
We'll use index tracking to handle step transitions and target the right inactive cards. No more hard-coded variables!
$("#section2play").ready(function() { // Get all content sections and inactive cards const $contents = $('.content'); const $inactiveCards = $('.inactive-card'); // Start with the index of the initially active content let currentStepIndex = $contents.filter('.active').index(); $('.button').click(function() { // Hide the current active content $contents.eq(currentStepIndex).removeClass('active').animate({ opacity: 0 }, 1000); // Move to the next step (loop back to first if we're at the last step) currentStepIndex = (currentStepIndex + 1) % $contents.length; // Show the new active content const $activeContent = $contents.eq(currentStepIndex).addClass('active'); $activeContent.css({ 'right': '10%', 'opacity': '1' }); // Handle inactive card animations based on current step if (currentStepIndex === 0) { // Reset all inactive cards to their initial state when back to Step 1 $inactiveCards.each(function(cardIndex) { // Calculate initial margin: 30px, 20px, 10px... based on card position const initialMargin = 30 - (cardIndex * 10); $(this).animate({ height: '8px', marginLeft: `${initialMargin}px`, marginRight: `${initialMargin}px` }, 100); }); } else { // For steps 2+, animate all inactive cards before the current step to 0 margin/height for (let i = 0; i < currentStepIndex; i++) { $inactiveCards.eq(i).animate({ height: '0', marginLeft: '0px', marginRight: '0px' }, 100); } } }); });
Step 3: Verify the Behavior
This updated code will do exactly what you want:
- Step 1 active: All inactive cards keep their original margins/heights
- Step 2 active: Only the first inactive card gets margin 0 / height 0
- Step 3 active: First + second inactive cards get margin 0 / height 0
- Step 4 active: First + second + third inactive cards get margin 0 / height 0
- Back to Step 1: All inactive cards reset to their initial state
Key Improvements
- Scalable: Add as many steps/inactive cards as you want—no need to rewrite logic
- Maintainable: No hard-coded variables tied to specific cards
- Predictable: Step-to-card mapping is based on index, so you won't get unexpected animations
内容的提问来源于stack exchange,提问作者Chris Castle

