Когда я пытаюсь добавить дочерний элемент к элементу, высота смещения элемента увеличивается. Даже когда используется переход, он просто мгновенно добавляет дочерний элемент. Я просто хочу сделать переход для этого.
const p = document.createElement("p");
p.innerText = "Sample text";
document.getElementById("main").appendChild(p);
div#main {
transition: all 0.5s ease;
}
<div id = "main"></div>
Вам нужно добавить элемент как невидимый/скрытый, а затем анимировать его переход в видимый вид. Также обратите внимание, что ваш текущий переход нацелен на элемент #main
, который всегда находится в DOM после загрузки страницы, а не на элемент p
, который вы создаете динамически.
Ниже приведен рабочий пример того, как это сделать с появлением opacity
, хотя подойдет любой метод; перелистывание по высоте/ширине, прокрутка текста, размытие и т. д.
Обратите внимание, что тайм-аут необходим для задержки удаления класса, который скрывает элемент, до тех пор, пока он не будет первоначально отображен в DOM:
const p = document.createElement("p");
p.classList.add('appended');
p.innerText = "Sample text";
document.getElementById("main").appendChild(p);
setTimeout(() => {
p.classList.remove('appended');
}, 25);
div p {
opacity: 1;
transition: opacity 0.5s ease;
}
div p.appended {
opacity: 0;
}
<div id = "main"></div>
Я хочу сделать переход для самой высоты.
Как я упоминал ранее, следуя той же идее @Rory McCrossan, вы также можете использовать высоту или размер шрифта для установки перехода.
const p = document.createElement("p");
p.innerText = "Sample text";
document.getElementById("main").appendChild(p);
setTimeout(()=>{p.classList.add('initial')},100)
setInterval(()=>{console.info(p.offsetHeight)},0.5)
p{
font-size : 0px;
transition: font-size 2s ease;
}
.initial{
font-size: 30px;
transition: font-size 2s ease;
}
<div id = "main"></div>
const p = document.createElement("p");
document.getElementById("main").appendChild(p);
setTimeout(()=>{p.classList.add('initial')},100)
setTimeout(()=>{p.innerText = "Sample text"},1000)
setInterval(()=>{console.info(p.offsetHeight)},0.5)
p{
height : 0px;
transition: height 1s ease;
background-color:yellow;
}
.initial{
height: 30px;
transition: height 1s ease;
}
<div id = "main"></div>
Вы можете анимировать высоту, но при добавлении дочернего элемента браузер мгновенно вычисляет новую высоту, и переход не применяется по умолчанию. Нам нужно явно установить высоту, а затем запустить переход.
У меня есть простое решение вашей проблемы с использованием Javascript. Здесь нам нужно использовать свойство анимации CSS для достижения желаемого результата. Вот как я решил эту проблему.
Я добавил событие window.click
. Итак, вы можете попробовать щелкнуть по окну, чтобы проверить анимацию для каждого добавленного элемента.
Я написал несколько комментариев к коду для большей ясности, и если что-то неясно, не стесняйтесь спрашивать, с удовольствием вам помогу.
(() => { // created a block for avoiding potential naming conflicts and keeping the global namespace clean.
const animationDuration = 500;
let animationTimeoutId = null;
const main = document.getElementById("main");
insertChild();
window.onclick = insertChild;
function insertChild() {
setPreviousHeight();
// Your code to insert a "p" element.
const p = document.createElement("p");
p.innerText = "Sample text";
document.getElementById("main").appendChild(p);
setCurrentHeight();
animate();
}
function setPreviousHeight() {
main.style.setProperty('--previous-height', main.scrollHeight+'px');
}
function setCurrentHeight() {
main.style.setProperty('--current-height', main.scrollHeight+'px');
}
function setAnimation() {
main.style.setProperty('animation', `animate-height ${animationDuration}ms ease`);
}
// removing "animation" property is needed to animate multiple time (whenever new content is appended).
function clearAnimation() {
main.style.removeProperty('animation');
clearTimeout(animationTimeoutId);
}
function animate() {
// Clears the previous timeout to prevent the new animation from being interrupted
// by the timeout set by any earlier animation.
clearTimeout(animationTimeoutId);
// Sets the CSS animation to run the height transition
setAnimation();
animationTimeoutId = setTimeout(clearAnimation, animationDuration);
}
})();
/**
* I have removed transition property to use animation property.
* --previous-height variable is used to animate only new appended content height.
*/
div#main {
--previous-height: 0px;
--current-height: 0px;
overflow: hidden; /* required */
}
/* Replaced transition with this animation keyframe. */
@keyframes animate-height {
from {
height: var(--previous-height);
}
to {
height: var(--current-height);
}
}
<div id = "main"></div>
Та же идея, что и у Рори МакКроссана. Вы также можете установить его высоту на 0 или размер шрифта на 0 и перевести его на желаемую высоту.