Надежный способ исчезнуть в новом элементе - PullRequest
1 голос
/ 22 июня 2019

В моем приложении я создаю новый элемент каждую секунду.Они должны быть исчезнут, как они созданы.Вот как я это сделал:

window.setInterval(() => {
    const element = document.createElement('div');
    element.classList.add('dot', 'hidden');
    document.getElementById('content').appendChild(element);
    element.classList.remove('hidden');
}, 1000);
.dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 5px 0;
    transition: opacity 1s;
}

.hidden {
    opacity: 0;
}

Я думал, что это заставит переход работать, но это не так.Я также попытался удалить класс hidden после задержки, например:

setTimeout(() => element.classList.remove('hidden'), 100);

Это интересно, потому что это работает, только если задержка достаточно велика.Если я установлю его на 10 мс, некоторые точки исчезнут, а другие появятся мгновенно.

Есть ли лучший, простой и надежный способ заставить его работать, без угадывания задержки setTimeout()?

Ответы [ 3 ]

1 голос
/ 22 июня 2019

Вы можете использовать CSS-анимации и избегать использования JavaScript, если вы хотите просто добавить его. Это будет работать только тогда, когда DOM-узел будет отображен на экране. Если вам нужен более расширенный контроль над вашими анимациями, вы можете использовать JS.

@keyframes fadein {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.dot {
   display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 5px 0;
    animation: 1s linear fadein;
 }
0 голосов
/ 22 июня 2019

Css transition работает лучше всего, когда вы прячете вещи.

Итак, вот решение, использующее только javascript.

window.setInterval(() => {
    const element = document.createElement('div');
    element.classList.add('dot');
    document.getElementById('content').appendChild(element);
    fade(element,0.1);
}, 1000);

// This will inc opacity by 0.1 each 100ms 
function fade(item, i){
i += 0.1;
item.style.opacity = i;
if (i< 1)
setTimeout(()=> fade(item,i), 100);
}
.dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 0px 5px;
}



#content {
background:black;
}
<div id="content"></div>
0 голосов
/ 22 июня 2019

Ваша первоначальная проблема имеет смысл, поскольку вы добавляете скрытый класс и удаляете его внутри той же функции в своем блоке setTimeout.Помните, что браузер получает возможность перерисовки только после завершения выполнения вашей функции.Это означает, что в строке, где вы добавляете свой класс hidden, нет никакой пользы, потому что он сразу же удаляется позже в функции (до того, как браузер сможет выполнить рендеринг).

Я бы рекомендовал вставить ваш элемент DOMи сбросьте его, используя setTimeout или requestAnimationFrame.Кроме того, поскольку временные параметры setInterval и setTimeout не являются полностью зависимыми, может иметь смысл использовать событие transitionend одного элемента, чтобы инициировать добавление следующего.

(function() {
  const container = document.getElementById('container');
  let count = 0;

  function addElement() {
    const div = document.createElement('div');
    div.innerHTML = 'item ' + ++count
    container.append(div);
    div.classList.add('item')
    div.addEventListener('transitionend', addElement)
    setTimeout(function() {
      div.classList.add('show')
    }, 0)
  }

  addElement()

})()
div {}

div.item {
  opacity: 0;
  transition: opacity 1s;
}

div.item.show {
  opacity: 1;
}
<hr>

<div id="container">

</div>
...