Angular打字动画场景下元素显示隐藏的逻辑问题求助
Fixing Angular Element Show/Hide Logic for Typing Animation
Hey there! Let's work through the issues in your current code and get that typing animation working smoothly in Angular.
First, let's break down what's going wrong with your existing logic:
- Nested
setIntervalchaos: You're creating nested intervals, which leads to overlapping timers piling up over time. This makes your timing completely unpredictable, since each string's timer fires almost simultaneously instead of sequentially. - Incorrect
durTotalcalculation: You overwritedurTotalin every iteration of thestrings.forEachloop. By the time the outersetIntervaluses it, it only holds the value from the last string—not the unique duration for each one. - DOM manipulation anti-pattern: Even though you commented out the
getElementByIdlines, relying on direct DOM access goes against Angular's philosophy. We should use component properties to control visibility, so Angular's change detection can handle updates properly. - Missing text binding: Your template's
<span>elements are empty—you need to bind the actual text you want to animate!
Here's the revised solution:
Step 1: Update your component's data structure
First, make sure your elements array links each span to its target text (this keeps everything organized in one place):
elements = [ { id: 'one', text: 'Your value', isSelected: false }, { id: 'two', text: 'Organic', isSelected: false }, { id: 'three', text: 'Gluteen-free', isSelected: false }, { id: 'four', text: 'Fair-trade', isSelected: false } ];
Step 2: Rewrite the animation logic (RxJS version, clean & Angular-friendly)
Using RxJS makes it easy to handle sequential timing without messy nested timers. Import the necessary operators first, then use this function:
import { concat, of } from 'rxjs'; import { delay, tap, repeat } from 'rxjs/operators'; startWriting() { const durCharFwd = 100; // Time per character to type (ms) const durFullGap = 2000; // Pause after finishing typing const durCharBwd = 80; // Time per character to delete (ms) const durDoneGap = 1000; // Pause before switching to next string // Create a sequence of animations for each string const animationSequence = concat( ...this.elements.map((el) => of(el).pipe( // Show the current string's span tap(() => this.elements.forEach(item => item.isSelected = item === el)), // Wait for typing + full pause delay(el.text.length * durCharFwd + durFullGap), // Hide the span (trigger delete animation) tap(() => el.isSelected = false), // Wait for delete + gap before next string delay(el.text.length * durCharBwd + durDoneGap) ) ) ); // Repeat the sequence infinitely animationSequence.pipe(repeat()).subscribe(); }
Step 3: Fix your template to display text
Update your template to bind the text and keep the visibility logic:
<ng-container *ngFor="let el of elements"> <span *ngIf="el.isSelected" [id]="el.id" class="animated-text">{{ el.text }}</span> </ng-container>
Step 4: Optional: Non-RxJS alternative (if you prefer plain JS)
If you don't want to use RxJS, a recursive setTimeout approach works too:
startWriting() { const durCharFwd = 100; const durFullGap = 2000; const durCharBwd = 80; const durDoneGap = 1000; let currentIndex = 0; const animateNextString = () => { // Show current string's span this.elements.forEach((el, i) => { el.isSelected = i === currentIndex; }); const currentEl = this.elements[currentIndex]; const typeTime = currentEl.text.length * durCharFwd; const deleteTime = currentEl.text.length * durCharBwd; // Schedule steps: type → pause → delete → pause → next setTimeout(() => { setTimeout(() => { currentEl.isSelected = false; setTimeout(() => { currentIndex = (currentIndex + 1) % this.elements.length; animateNextString(); }, durDoneGap); }, deleteTime); }, typeTime + durFullGap); }; // Start the animation loop animateNextString(); }
Key improvements:
- Sequential timing: Animations run one after another, no overlapping timers.
- Angular-compliant: Uses component properties to control visibility, so change detection works as expected.
- Maintainable logic: All timing and string data is centralized, making it easy to adjust values later.
内容的提问来源于stack exchange,提问作者ind888
相关产品推荐
相关产品推荐

