在为 textContent 赋值和在 JS 中切换 class 时遇到问题

Having trouble with assigning a value to textContent and toggling a class in JS

我正在显示存储在嵌套数组中的引号。 当用户按下一个按钮时,我生成一个随机数并将随机数组索引的内容分配给标题和段落元素的 textContent。这很好用。

分配值后,我切换 class 使文本淡入。

出于某种原因,只有每隔一秒的引用才会淡入。

我应该怎么做?

注意。 quotes 是嵌套的引号数组。

    const quotes = [
      ["quote 1", "author 1"],
      ["quote 2", "author 2"],
      ["quote 3", "author 3"],
      ["quote 4", "author 4"],
    ]
let quoteCount = 0;
let currentQuote = 0;
let quotesServed = [];

function getQuote(event) {
    let nextQuote = 0;
    let randomQuote = 0;
    let prevQuote = 0;
    let elementHeading = document.getElementById('quoteheadingID');
    let elementAuthor = document.getElementById('quoteauthorID');
    const whichButton = event.target.classList.contains('next')? "next" : "previous";
    
    if (whichButton==="next") {
        if (quoteCount === quotesServed.length) {
            do {
            randomQuote = Math.floor(Math.random()*quotes.length);
            } while (randomQuote === quotesServed[quoteCount-1])
    
            
            elementHeading.textContent = quotes[randomQuote][0];
            elementHeading.classList.toggle('fadein');
            
            elementAuthor.textContent = quotes[randomQuote][1];
            elementAuthor.classList.toggle('fadein');
            
    
            quotesServed.push(randomQuote);
            quoteCount++;
            
            
        } else {
            if (quoteCount < quotes.length ) {
                nextQuote = quotesServed[quoteCount];
                
            
                elementHeading.textContent = quotes[nextQuote][0];
                elementHeading.classList.toggle('fadein');
                elementAuthor.textContent = quotes[nextQuote][1];
                elementAuthor.classList.toggle('fadein');
                quoteCount++;
            } 
        }

    } else if (whichButton==="previous") {
        if (quoteCount > 1) {
            quoteCount--;
            prevQuote = quotesServed[quoteCount-1];
            elementHeading.textContent = quotes[prevQuote][0];
            elementHeading.classList.toggle('fadein');
            elementAuthor.textContent = quotes[prevQuote][1];
            elementAuthor.classList.toggle('fadein');
            
        }
    }
    
}

    document.querySelector('.next').addEventListener('click', getQuote);
    document.querySelector('.previous').addEventListener('click', getQuote);
.fadein {
  animation: fadeIn linear 7s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<div class="quote_container">

  <figure class="quotefigure">
    <img class="quoteimage" src="./Resources/Images/flag.jpg" alt="" srcset="">
  </figure>
  <div class="quotetext_container">
    <h1 id="quoteheadingID" class="quoteheading fadein"></h1>
    <p id="quoteauthorID" class="quoteauthor fadein"></p>
  </div>
  <div class="prevnext_container">
    <a href="#" class="previous">&#8249;</a>
    <a href="#" class="next">&#8250;</a>
  </div>
</div>

所以关键帧不会restart after having been triggered

您需要重新插入使用它们的HTML

我在点击时打乱数组而不是随机化

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array
}
const quotes = shuffleArray([
  ["quote 1", "author 1"],
  ["quote 2", "author 2"],
  ["quote 3", "author 3"],
  ["quote 4", "author 4"],
]);

const container = document.querySelector('.quote_container'),
  navContainer = document.querySelector('.prevnext_container');

let cnt = 0;
const navigate = e => {
  // restart animation
  const  textContainer = document.querySelector('.quotetext_container')
  const newContainer = textContainer.outerHTML
  textContainer.remove()
  navContainer.insertAdjacentHTML('beforebegin',newContainer);
  const elementHeading = document.getElementById('quoteheadingID'),
    elementAuthor = document.getElementById('quoteauthorID');
  // if called without an event we are loading the first entry
  let dir = 0; // handle first load
  // else use whatever was clicked
  if (e && e.target) dir = e.target.id === 'next' ? 1 : -1;
  cnt += dir
  // reset - here you can wrap if you want
  if (cnt < 0) cnt = 0;
  else if (cnt >= quotes.length - 1) cnt = quotes.length - 1;
  // get the author and quote
  const [q, a] = quotes[cnt];
  elementHeading.innerHTML = q;
  elementAuthor.innerHTML = a;

}

document.querySelector('.prevnext_container').addEventListener('click', navigate);
navigate()
.fadein {
  animation: fadeIn linear 7s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<div class="quote_container">

  <figure class="quotefigure">
    <img class="quoteimage" src="./Resources/Images/flag.jpg" alt="" srcset="">
  </figure>
  <div class="quotetext_container fadein">
    <h1 id="quoteheadingID" class="quoteheading"></h1>
    <p id="quoteauthorID" class="quoteauthor"></p>
  </div>
  <div class="prevnext_container">
    <a href="#" class="nav" id="previous">&#8249;</a>
    <a href="#" class="nav" id="next">&#8250;</a>
  </div>
</div>

在得到一些帮助并在网上进行了更多搜索后,我发现了一种更可靠的重置动画的方法,这要归功于 MDN 上的一篇文章:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Tips

function play(index) {
    const [q, a] = quotes[index];
    let elementHeading = document.getElementById('quoteheadingID');
    let elementAuthor = document.getElementById('quoteauthorID');
        
    document.querySelector(".quoteheading").className = "quoteheading";
    window.requestAnimationFrame(function(time) {
        window.requestAnimationFrame(function(time) {
            elementHeading.textContent = q;
            document.querySelector(".quoteheading").className = "quoteheading fadein";
        });
    });

    document.querySelector(".quoteauthor").className = "quoteauthor";
    window.requestAnimationFrame(function(time) {
        window.requestAnimationFrame(function(time) {
            elementAuthor.textContent = a;
            document.querySelector(".quoteauthor").className = "quoteauthor fadein";
        });
    });

    
}
 

完美运行