Запуск CSS анимации при изменении JS textContent - PullRequest
0 голосов
/ 12 октября 2018

Я в основном создаю простое приложение для викторины.Прямо сейчас, когда вопрос неправильный, он обновляет textContent пространства вопросов, чтобы пользователь знал, что он ошибался.Затем после setTimeOut снова возвращается к вопросу.

Это прекрасно работает, когда вещи стоят.Прямо сейчас, хотя эти изменения происходят мгновенно, и я хочу, чтобы они затем исчезли. Я пытался выяснить это, просто изменив непрозрачность, хотя сейчас ничто не влияет на это.Таким образом, я полагаю, что либо неправильно настраиваю анимацию (очень возможно), либо я делаю что-то не так в JavaScript.

Итак, что я ищу:

  1. Исчезать в новом текстовом контенте, сообщая пользователю, что вопрос был неправильным
  2. Подождите 1 секунду 3. Исчезните новый текстовый контент и заменитесо старым содержанием вопроса.

Для 1 и 3: я думаю, что это можно сделать, создав простую анимацию ключевого кадра, а затем перевернув ее.(непрозрачность от 100 до 0%, затем от 0 до 100).

Я могу подождать 1 секунду с моим setTimeout, так как сейчас все в порядке, я просто не уверен, как убедиться, что анимация запускает выполнение fadeEffect.

Я использую Vanilla Js (предпочитаю не Jquery), может кто-нибудь указать мне правильное направление здесь?

Jsfiddle: https://jsfiddle.net/ubw97kfe/ Я добавил комментарии, чтобы указать наконкретные элементы кода, на которые я ссылаюсь.

// Title of Question Set
const title = document.querySelector(".input_title-input");

// Array of Questions
const questions = [];
let chosen = [];

// Selected Question
let qChosen = [];

// Toggles if a new question is selected
let toggle = 0;

// Selecting Inputs and Button
let question = document.querySelector(".input_question-input");
let answer = document.querySelector(".input_answer-input");
let submit = document.querySelector(".input_submit-button");
let display = document.querySelector(".input_display");
let card = document.querySelector(".card_container");
let start = document.querySelector(".input_start-btn");
let guessInput = document.querySelector(".guess_input");
let submitGuess = document.querySelector(".submitGuess");
let nextQuestion = document.querySelector(".nextQuestion");

// Select all display items
let displayItems = document.getElementsByClassName("input_display-item");

// Select LI quiz card values
let cardQuestion = document.querySelector(".quiz_question");
let cardAnswer = document.querySelector(".quiz_answer");

// Event Listener on Submit Button for Display Items Idividually
submit.addEventListener("click", function() {
    if (question.value === "" || answer.value === "") {
        question.classList.toggle("error");
        answer.classList.toggle("error");
    } else {
        createObj();

        let trashCan = createDisplayItem();
        trashCan.dataset.index = questions.length - 1;
        trashCan.addEventListener("click", function(e) {
            start.disabled = true;
            questions.splice(this.dataset.index, 1);
            // this.parentNode.remove();
            let thisItem = this.parentNode;
            fadeOutIn(thisItem, 1000);

            
            console.log(questions.length);
        });
        inputReset();
        toggle = questions.length;
        start.removeAttribute("disabled");


        console.log(questions.length);
    }
});

start.addEventListener("click", function() {
    generateCard();
    hideInputs();
});




/* ============================================
==============================================*/

// Event Listener to test if guess is correct
submitGuess.addEventListener("click", function() {
    if (guessInput.value.toLowerCase() === qChosen.answer.toLowerCase()) {
        card.classList.toggle("flip");
        submitGuess.disabled = true;
    } else {
        // Insert wrong message here
        cardQuestion.textContent = "You have guessed incorrectly. Please Try Again";
        // SetTimeout to reset back to Chosen Question
        setTimeout(function(){
            cardQuestion.textContent = qChosen.question;
        }, 1000);
    }
});


/* ============================================
==============================================*/


// Selects the Next question
nextQuestion.addEventListener("click", function() {
    card.classList.toggle("flip");
    guessInput.value = "";
    submitGuess.disabled = false;
    setTimeout(generateCard, 1000);
});

// Create The object for inclusion to array
function createObj() {
    let obj = {};
    obj.question = question.value;
    obj.answer = answer.value;
    questions.push(obj);
}

// Resets inputs to blank after submit
function inputReset() {
    question.value = "";
    answer.value = "";
    if (question.classList.contains("error")) {
        question.classList.toggle("error");
        answer.classList.toggle("error");
    }
}

// Creates Each Display Item
function createDisplayItem() {
    // Create new Div
    let newUl = document.createElement("ul");

    // Create Li and Image Elements
    let liQuestion = document.createElement("li");
    let liAnswer = document.createElement("li");
    let trashCan = document.createElement("img");

    // Set img src
    trashCan.src = "../assets/trash.svg";

    // Set classes
    newUl.className = "input_display-item";
    liQuestion.className = "input_display-question";
    liAnswer.className = "input_display-answer";
    trashCan.className = "input_display-delete";

    // Set LI textContent
    liQuestion.textContent = question.value;
    liAnswer.textContent = answer.value;

    // Append Children
    display.appendChild(newUl);
    newUl.appendChild(liQuestion);
    newUl.appendChild(liAnswer);
    return newUl.appendChild(trashCan);
}

//Generating Card Information per question
function generateCard() {
    random();
    if (toggle < 0) {
        cardQuestion.textContent = "There are no more questions left";
        cardAnswer.textContent = "There are no more questions left";
    } else {
        cardQuestion.textContent = qChosen.question;
        cardAnswer.textContent = qChosen.answer;
    }
}

// Choses a random value for the selection set
function random() {
    if (questions.length === 0) {
        toggle = -1;
    } else {
        let num = Math.floor(Math.random() * questions.length);
        chosen = questions.splice(num, 1).concat(chosen);
        qChosen = chosen[0];
    }
}

// hides all the inputs when start quiz is selected
function hideInputs(){
    for(let i = 0; i < displayItems.length; i++){
        fadeOutIn(displayItems[i], 1000);
    }
}

// FadeOut the display items when trashCan is clicked.
function fadeOutIn(elem, speed){
    if(!elem.style.opacity){
        elem.style.opacity = 1;
    }

    var outInterval = setInterval(function(){
        elem.style.opacity -= 0.02;
        if(elem.style.opacity <=0){
            clearInterval(outInterval);
            elem.remove();
        }
    }, speed/50)
}
/** Variables
 ---------------------------------------------------------*/
/** Reset
 ---------------------------------------------------------*/
* {
  margin: 0;
  padding: 0; }

*,
*::before,
*::after {
  -webkit-box-sizing: inherit;
  box-sizing: inherit; }

html {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  font-size: 62.5%; }

body {
  font-weight: 400;
  line-height: 1.5;
  font-size: 2rem;
  background-color: #bdbdc7; }

/** Primary Container
 ---------------------------------------------------------*/
.container {
  max-width: 180rem;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex; }

.flex {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center; }

.fadeOut {
  visibility: hidden;
  transition: all 0.5s ease-out; }

/** Input Section
 ---------------------------------------------------------*/
input[type="text"] {
  padding: 0.5rem;
  width: auto;
  min-width: 100%;
  line-height: 2rem; }

.input {
  width: 40rem;
  height: 100vh;
  padding: 1rem;
  background-color: #ccc;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: start;
  -ms-flex-align: start;
  align-items: flex-start;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column; }
  .input_title {
    width: 100%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column; }
    .input_title-label {
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: center;
      -ms-flex-pack: center;
      justify-content: center; }
    .input_title-input {
      padding: 0.5rem; }
  .input_question {
    width: 100%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column; }
    .input_question-label {
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: center;
      -ms-flex-pack: center;
      justify-content: center; }
    .input_question-input {
      padding: 0.5rem; }
  .input_answer {
    width: 100%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column; }
    .input_answer-label {
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: center;
      -ms-flex-pack: center;
      justify-content: center; }
    .input_answer-input {
      padding: 0.5rem; }
  .input_question-input.error, .input_answer-input.error {
    border: 2px red solid; }
  .input_submit {
    width: 100%; }
    .input_submit-button {
      margin-top: 1rem;
      padding: 0 1.5rem; }
  .input_start {
    width: 100%; }
  .input_display {
    width: 100%;
    font-size: 1.5rem;
    padding: 2rem 0 1rem 0; }
    .input_display-item {
      margin-bottom: 1rem;
      padding: .2rem 2rem;
      text-transform: capitalize;
      background-color: #fff;
      border-radius: 1rem;
      list-style: none;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: justify;
      -ms-flex-pack: justify;
      justify-content: space-between;
      -webkit-box-align: center;
      -ms-flex-align: center;
      align-items: center; }
    .input_display-item:nth-child(odd) {
      background-color: #aaa;
      border-radius: 1rem; }
    .input_display-delete {
      height: 1.8rem;
      width: 1.8rem; }

.input :not(.input_display) div {
  padding-bottom: 2rem; }

/** Quiz Card
 ---------------------------------------------------------*/
.card {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  width: 100%; }
  .card_container {
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    -webkit-perspective: 1000px;
    perspective: 1000px;
    width: 60rem;
    margin: 1rem;
    cursor: pointer; }
    .card_container .front {
      -webkit-transform: rotateY(0deg);
      transform: rotateY(0deg);
      -webkit-transform-style: preserve-3d;
      transform-style: preserve-3d; }
      .card_container .front:after {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
        width: 100%;
        height: 100%;
        content: "";
        display: block;
        opacity: 0.6;
        background-color: #000;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
        border-radius: 10px; }
    .card_container .back {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      background-color: #cedce7;
      background: linear-gradient(45deg, #dedce7 0%, #596a72 100%);
      -webkit-transform: rotateY(180deg);
      transform: rotateY(180deg);
      -webkit-transform-style: preserve-3d;
      transform-style: preserve-3d; }
    .card_container .front,
    .card_container .back {
      background-color: red;
      background-size: cover;
      background-position: center;
      -webkit-transition: -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
      transition: -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
      transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
      transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1), -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
      transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
      -webkit-backface-visibility: hidden;
      backface-visibility: hidden;
      text-align: center;
      min-height: 500px;
      height: auto;
      border-radius: 10px;
      color: #fff;
      font-size: 1.5rem; }

.flip {
  -webkit-transition: -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
  transition: -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
  transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
  transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1), -webkit-transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
  transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1); }
  .flip .back {
    -webkit-transform: rotateY(0deg);
    transform: rotateY(0deg);
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d; }
  .flip .front {
    -webkit-transform: rotateY(-180deg);
    transform: rotateY(-180deg);
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d; }

.inner {
  -webkit-transform: translateY(-50%) translateZ(60px) scale(0.94);
  transform: translateY(-50%) translateZ(60px) scale(0.94);
  top: 50%;
  position: absolute;
  left: 0;
  width: 100%;
  padding: 2rem;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  outline: 1px solid transparent;
  -webkit-perspective: inherit;
  perspective: inherit;
  z-index: 2; }


/* The particular element applying the animation
==============================================*/

.quiz_question {
  animation: fade 10s linear; }

/* ============================================
==============================================*/



.front .inner p {
  font-size: 2rem;
  margin-bottom: 2rem;
  position: relative; }

.card_container-guess {
  padding-top: 2rem; }
  .card_container-guess .guess_input {
    width: 2rem;
    margin: 1rem auto;
    padding: 1rem;
    border-radius: 1rem;
    -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.55), 0px 1px 1px rgba(255, 255, 255, 0.5);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.55), 0px 1px 1px rgba(255, 255, 255, 0.5);
    border: 1px solid #666;
    opacity: 0.6;
    outline: none; }
    .card_container-guess .guess_input:hover, .card_container-guess .guess_input:focus {
      opacity: .8;
      color: #08c;
      -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25), inset 0px 3px 6px rgba(0, 0, 0, 0.25);
      box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.25), inset 0px 3px 6px rgba(0, 0, 0, 0.25); }
  .card_container-guess-buttons {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between; }
    .card_container-guess-buttons .btnNew {
      margin: 1rem 2rem; }

.btnNew {
  height: 5rem;
  width: 12rem;
  margin: 1.5rem 3rem 1rem 1rem;
  font-weight: 700;
  color: #333;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#f4f1ee), to(#fff));
  background-image: linear-gradient(to bottom, #f4f1ee, #fff);
  -webkit-box-shadow: 0px 8px 30px 1px rgba(0, 0, 0, 0.3), inset 0px 4px 1px 1px white, inset 0px -3px 1px 1px rgba(204, 198, 197, 0.5);
  box-shadow: 0px 8px 30px 1px rgba(0, 0, 0, 0.3), inset 0px 4px 1px 1px white, inset 0px -3px 1px 1px rgba(204, 198, 197, 0.5);
  border-radius: 5%;
  position: relative;
  -webkit-transition: all .1s linear;
  transition: all .1s linear;
  outline: none; }

.btnNew:after {
  color: #e9e6e4;
  content: "";
  display: block;
  font-size: 30px;
  height: 3rem;
  text-decoration: none;
  text-shadow: 0px -1px 1px #bdb5b4, 1px 1px 1px white;
  position: absolute;
  width: 3rem; }

.btnNew:hover {
  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f4f1ee));
  background-image: linear-gradient(to bottom, #fff, #f4f1ee);
  color: #0088cc; }

.btnNew:active {
  background-image: -webkit-gradient(linear, left top, left bottom, from(#efedec), to(#f7f4f4));
  background-image: linear-gradient(to bottom, #efedec, #f7f4f4);
  -webkit-box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4), inset opx -3px 1px 1px rgba(204, 198, 197, 0.5);
  box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4), inset opx -3px 1px 1px rgba(204, 198, 197, 0.5);
  outline: none; }

.btnNew:active:after {
  color: #dbd2d2;
  text-shadow: 0px -1px 1px #bdb5b4, 0px 1px 1px white;
  outline: none; }


/* KeyFrame Animation in question */
@keyframes fade {
  0% {
    opacity: 100%; }
  100% {
    opacity: 0%; } }
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Flash</title>

    <!-- Custom CSS -->
    <link rel="stylesheet" href="css/main.css">
</head>

<body>
    <div class="container">
        <section class="input">
            <div class="input_title">
                <label class="input_title-label" for="title">Enter a Title</label>
                <input class="input_title-input" id="title" type="text" placeholder="List of Towels">
            </div>

            <div class="input_question">
                <label class="input_question-label" for="question">Enter a Question</label>
                <input class="input_question-input" id="question" type="text" placeholder="What is 42?">
            </div>

            <div class="input_answer">
                <label class="input_answer-label" for="answer">Enter an Answer</label>
                <input class="input_answer-input" id="answer" type="text" placeholder="The Meaning Life, Universe, and Everything">
            </div>

            <div class="input_submit flex">
                <button class="input_submit-button btnNew">Submit</button>
            </div>

            <div class="input_display"></div>

            <div class="input_start flex">
                <button type="button" class="input_start-btn btnNew" disabled>Start Quiz</button>
            </div>
        </section>

        <section class="card">
            <div class="card_container">
                <div class="front">
                    <div class="inner">
                        <p class="quiz_question">Please Set Some Questions Up</p>
                    </div>
                </div>

                <div class="back">
                    <div class="inner">
                        <p class="quiz_answer"></p>
                    </div>
                </div>

                <div class="card_container-guess">
                    <input type="text" class="guess_input">
                    <div class="card_container-guess-buttons">
                        <button class="submitGuess btnNew">Submit Guess</button>
                        <button class="nextQuestion btnNew">Next Question</button>
                    </div>
                </div>
            </div>
        </section>
    </div>


    <!-- Custom JS -->
    <script src="js/scripts.js"></script>
</body>

</html>

1 Ответ

0 голосов
/ 17 октября 2018

Основная проблема заключается в том, что вы хотите заменить строку другой строкой.Таким образом, вы не можете на самом деле исчезать первое и исчезать во второе в один и тот же момент.Вы можете сделать еще одну карточку переполнением и поместить ее поверх карточки вопроса, чтобы иметь больше контроля над анимацией и стилем текста.

Я заменил submitGuess.addEventListener на этот:

    // Event Listener to test if guess is correct
submitGuess.addEventListener("click", function() {
  if (guessInput.value.toLowerCase() === qChosen.answer.toLowerCase()) {
    card.classList.toggle("flip");
    submitGuess.disabled = true;
  } else {
    // Insert wrong message here
    cardQuestion.style.animation="colorfadeerr 0.5s ease-in-out forwards";
    // SetTimeout to reset back to Chosen Question
    setTimeout(function(){
      cardQuestion.style.animation="colorfadequestion 0.3s ease-in-out";            
    }, 1500);
  }
});

cardQuestion.addEventListener("animationstart", function() {
  if(cardQuestion.textContent === qChosen.question)
    cardQuestion.textContent = "You have guessed incorrectly. Please Try Again";
  else
    cardQuestion.textContent = qChosen.question;
});

И добавил это в css:

@keyframes colorfadeerr {
  0% {
    color: rgba(255,255,255,0.0); }
  10% {
    color: rgba(255,255,255,0.0); } 
  100% {
    color: rgba(255,200,200,1.0); } 
    }

@keyframes colorfadequestion {
  0% {
    color: rgba(255,255,255,0.0); }
  30% {
    color: rgba(255,255,255,0.0); } 
  100% {
    color: rgba(255,255,255,1.0); } 
    }

Первая анимация скроет текст и покажет вам сообщение об ошибке другим цветом.Вторая анимация покажет вам первый текст снова (белый).

Я не знаю, может ли это вам помочь.Я пытался оставить его похожим на ваш код.Но, как уже говорилось, эффект был бы лучше, если бы вы могли поставить еще одну карту поверх вашего вопроса.Таким образом, у вас есть исчезновение вопроса и появление сообщения об ошибке одновременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...