Как реализовать обещания в ванильном JavaScript, чтобы дождаться завершения переходов? - PullRequest
0 голосов
/ 23 января 2019

Мне трудно перебирать список элементов и добавлять и выводить их с помощью ванильного javascript. Допустим, у меня есть список строк ["cat", "ball", "bat", "mouse"].

Я хочу просмотреть эти элементы и отобразить их один за другим. Например, сначала мне нужно отобразить «cat», а затем перейти к отображению «bat». Чтобы сделать это, я должен сначала подождать, пока «кошка» не исчезнет, ​​дождаться ее исчезновения, а затем отобразить «летучая мышь». В настоящее время я просто использую цикл for, цикл идет прямо к концу списка "mouse" и не ждет, пока другие элементы закончат исчезать.

Чтобы исправить это, я знаю, что мне нужно использовать асинхронное программирование, обратные вызовы, API обещаний и т. Д., Но я не слишком много работал с ними, поэтому я не знаю, как реализовать это решение. Любая помощь или ясность в том, как использовать асинхронное программирование вместе с setInterval (), очень ценится.

Вот фрагмент моего кода:

var textarr = ["cat", "ball", "bat", "mouse"]
for(let i=0; i<textarr.length; i++){
  var text_item = document.getElementById('text_item');
  text_item.style.opacity = 0;
  text_item.innerHTML = textarr[i];
  // problem lies here; this is skipping to end of the list (mouse)
  fadeIn(text_item);
}

//function borrowed from stack overflow to fadeIn elements

function fadeIn(element) {
    var op = 0.1;  // initial opacity
    element.style.display = 'block';
    var timer = setInterval(function () {
        if (op >= 1){
            clearInterval(timer);
        }
        element.style.opacity = op;
        element.style.filter = 'alpha(opacity=' + op * 100 + ")";
        op += op * 0.1;
    }, 100);
}

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Лучший способ - использовать очередь, в которой таймер выбирает элемент из списка, а затем выполняет действие. В этом случае я кодировал его с помощью CSS-переходов, чтобы сделать простое затухание.

// Made it a function so you could use 
// it more than once on same page
function changeText (arr, elem, startIndex) {
  // holds active slide
  let current = startIndex || 0
  // Called when we what to show the current word
  const update = function () {
    // set the word on the page
    elem.innerHTML = arr[current]
    // Add the class to start transition
    elem.classList.add('fadeIn')
    // How long you want the word to stay on the screen
    // When timer executes it calls function to reverse
    // the annimation
    window.setTimeout(next, 3000)  // 3 seconds
  }
  // Called to do the reverse animation and update the step
  const next = function () {  
    // remove the class so goes back to zero
    elem.classList.remove('fadeIn')
    // update what slide we are on
    current++
    // If we are over the limit, than restart
    if (current===arr.length) {
      current = 0  // back to first slide
    }
    // How long do you want for the fade out transition to
    // take to execute. 
    window.setTimeout(update, 300);  // 300 milliseconds
  }
  // initialize it so first word shows up
  update();
}

var textarr = ["cat", "ball", "bat", "mouse"]
changeText(textarr, document.querySelector('.text1'))

changeText(textarr, document.querySelector('.text2'), 3)
.text {
  opacity: 0;  
  transition: opacity .3s ease-in-out;
}

.fadeIn {
  opacity: 1;
  transition: opacity 2s ease-in-out;
}
<h1>One</h1>
<div class="text text1"></div>
<h2>Another one</h2>
<div class="text text2"></div>
0 голосов
/ 23 января 2019

Использование события transitionend, которое @RwwL упомянул в комментариях:

let display = document.getElementById('display');
const animals = ['dog', 'cat', 'mouse'];
let i = 0;

display.addEventListener('transitionend', function(event) {
  if (i < animals.length) {
    if (!display.classList.contains('fadeIn')) {
      display.innerHTML = animals[i++];
    }
    display.classList.toggle('fadeIn');
  }
}, false);

// Set timeout, otherwise the transition won't take effect (there are ways around this)
setTimeout(() => {
  display.classList.toggle('fadeIn');
}, 1000);
#display {
  color: #FFFFFF;
  transition: color 1s ease-in;
}

#display.fadeIn {
  color: #000000;
}
<div id="display">Animal Names Here</div>
...