сейчас я разбираюсь с анимационными эффектами с помощью css и javascript и хочу реализовать алгоритм похожий на VueJs чтобы лучше понимать как это все работает и вот столкнулся с несколькими проблемами и вопросами.
Почему в обработчике события для btnShow если я не буду использовать таймер на 0 секунд, то у меня просто не сработает анимация, ведь алгоритм вроде правильный сначала ставлю класс enter, чтобы задать начальные стили, потом задаю enter-active - для изменения начальных стилей, потом сразу удаляю enter, и когда сработает событие transitionend уберу обработчик события на элемент. В теории все должно работать, но на практике получается все не так, анимация во все не работает, js вообще не ставит класс enter, я конечно догадываюсь, что это такая оптимизация браузера и что типа браузер видит добавление, а потом удаление класса и вообще его не ставит, но все равно я не понимаю как это работает и почему. Почему браузер не выполняет команды подряд, почему код ведет себя так непредсказуемо, что этому способствует?
elem.style.display = 'inline-block';
elem.classList.add('enter');
elem.classList.add('enter-active');
elem.classList.remove('enter');
Почему settimeout это исправляет?
Почему опять же если я чуть меняю алгоритм и здесь уже сразу после enter добавляю enter-active, то анимация тоже не сработает, браузеру именно надо чтоб я добавил сначала enter, а потом ставил интервал и только в нем уже добавлял новый класс и удалял старый. Почему так ? Как это вообще работает, уже голова кругом если честно))
elem.style.display = 'inline-block'; elem.classList.add('enter'); elem.classList.add('enter-active'); setTimeout(function() { elem.classList.remove('enter'); }, 0);
Заранее большое спасибо, если объясните как это все работает в браузере и почему надо делать именно так, чтоб в дальнейшем это не было сюрпризом для меня))
var btnHide = document.querySelector('.hide');
var btnShow = document.querySelector('.show');
var elem = document.querySelector('.block');
btnHide.addEventListener('click', function () {
elem.classList.add('leave-active');
function handler() {
elem.style.display = "none";
elem.classList.remove('leave-active');
elem.removeEventListener('transitionend', handler);
}
elem.addEventListener('transitionend', handler);
});
btnShow.addEventListener('click', function () {
elem.style.display = 'inline-block';
elem.classList.add('enter');
// elem.classList.add('enter-active'); ??
setTimeout(function() {
elem.classList.remove('enter');
elem.classList.add('enter-active');
}, 0);
elem.addEventListener('transitionend', function() {
elem.classList.remove('enter-active');
});
});
.block {
background: greenyellow;
display: inline-block;
margin: 15px;
}
.leave-active {
transition: opacity, 1s;
opacity: 0;
transform: translateX(200px);
}
.enter {
opacity: 0;
transform: translateX(-200px)
}
.enter-active {
transition: opacity 1s, transform 1s;
opacity: 1;
}
<div class="btns">
<button class="hide">Hide</button>
<button class="show">Show</button>
</div>
<div class="block">
<p>Lorem ipsum dolor sit amet.</p>
<p>Vitae nemo labore autem tempora.</p>
<p>Tenetur earum ab suscipit unde?</p>
<p>Labore eius accusantium ullam voluptatum.</p>
<p>Necessitatibus similique mollitia cumque incidunt.</p>
</div>
<div class="some">
<p>Lorem, ipsum.</p>
</div>
https://developer.mozilla.org/ru/docs/Web/API/Element/classList
elem.classList.toggle( String [, Boolean])
Если класс у элемента отсутствует - добавляет, иначе - убирает.
Когда вторым параметром передано false - удаляет указанный класс, а если true - добавляет.
var btnHide = document.querySelector('#hide');
var btnShow = document.querySelector('#show');
var elem = document.querySelector('.block');
// --
btnHide.addEventListener('click', function() {
// это
// elem.classList.remove('enter');
// elem.classList.add('leave');
// заменятся на это
elem.classList.toggle("leave");
});
// --
btnShow.addEventListener('click', function() {
// это
// elem.classList.remove('leave');
// elem.classList.add('enter');
// заменятся на это
elem.classList.toggle("leave");
});
// --
.block {
background: greenyellow;
display: inline-block;
margin: 15px;
overflow: hidden;
height: 250px;
/*показываем медленнее*/
transition: height 4s, opacity 1s, transform 1s;
/* это для наглядности - удалить
opacity: 1;
transform: translateX(0px)
*/
}
.leave {
/*прячем - быстрее*/
transition: height 2s, opacity 1s, transform 1s;
opacity: 0;
height: 0;
transform: translateX(200px);
}
/* это для наглядности - удалить
.enter {
opacity: 1;
transform: translateX(0px)
}
*/
<div class="btns">
<button id="hide">Hide</button>
<button id="show">Show</button>
</div>
<div class="block">
<p>Lorem ipsum dolor sit amet.</p>
<p>Vitae nemo labore autem tempora.</p>
<p>Tenetur earum ab suscipit unde?</p>
<p>Labore eius accusantium ullam voluptatum.</p>
<p>Necessitatibus similique mollitia cumque incidunt.</p>
</div>
<div class="some">
<p>Lorem, ipsum.</p>
</div>
у этого примера есть недостаток - необходимо заранее знать высоту
.block {
height: 250px;
}
эта проблема решается с помощью JS так
var btnHide = document.querySelector('#hide');
var btnShow = document.querySelector('#show');
var elem = document.querySelector('.block');
// --
btnHide.addEventListener('click', function() {
// это
// elem.classList.remove('enter');
// elem.classList.add('leave');
// заменятся на это
elem.classList.toggle("leave");
});
// --
btnShow.addEventListener('click', function() {
// это
// elem.classList.remove('leave');
// elem.classList.add('enter');
// заменятся на это
elem.classList.toggle("leave");
});
// --
let elStyle = getComputedStyle(elem);
document.head.insertAdjacentHTML('beforeend', `
<style>
.block {
background: greenyellow;
display: inline-block;
margin: 15px;
overflow: hidden;
height: ${elStyle.height};
/*показываем медленнее*/
transition: height 4s, opacity 1s, transform 1s;
}
.leave {
/*прячем - быстрее*/
transition: height 2s, opacity 1s, transform 1s;
opacity: 0;
height: 0;
transform: translateX(200px);
}
</style>
`)
<div class="btns">
<button id="hide">Hide</button>
<button id="show">Show</button>
</div>
<div class="block">
<p>Lorem ipsum dolor sit amet.</p>
<p>Vitae nemo labore autem tempora.</p>
<p>Tenetur earum ab suscipit unde?</p>
<p>Labore eius accusantium ullam voluptatum.</p>
<p>Necessitatibus similique mollitia cumque incidunt.</p>
</div>
<div class="some">
<p>Lorem, ipsum.</p>
</div>
Виртуальный выделенный сервер (VDS) становится отличным выбором
Подскажите скрипт аудиоплеера, который можно было бы использовать с минимальными изменениями в разметке - например, задать соответствующие...
Не могу понять, каким образом стоит отлавливать действия пользователя в модальном окне
помогите посчитать значения всех inputПробовал преобразовать значение инпут с помощью parseInt, считает некорректно