Плавное изменение размера Javascript при отображении дополнительного текста

#javascript #html #css #css-animations

#javascript #HTML #css #css-анимация

Вопрос:

У меня есть некоторый текст на моем веб-сайте, но для его одновременного отображения он займет слишком много места. Итак, я создал простую кнопку, при нажатии на которую отображается весь дополнительный текст, который обычно скрыт с помощью display: none . Это работает отлично, но в настоящее время не анимировано и не слишком хорошо соответствует теме веб-сайта.

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

HTML:

 <h3 style="margin-bottom: 0.3em;">some text</h3>
<p>some more text</p>
                        
<span id="more" style="display: none; transition: all .5s linear;">
    <h3 style="margin-bottom: 0.3em;">Some hidden text</h3>
    <p>some more hidden text</p>
</span>

<button id="readMore" onclick="readMore()">Read more</button>
  

Javascript:

 var active = false;
var moreText = document.getElementById("more");
var button = document.getElementById("readMore");

function readMore()
{
    if(active == false)
    {
        active = true;
        moreText.style.display = "inline";
        button.innerHTML = "Read less";
    }
    else if(active == true)
    {
        active = false;
        moreText.style.display = "none";
        button.innerHTML = "Read more";
    }
}
  

Этот код работает отлично, за исключением transition: all .5s linear; , потому что он в настоящее время не анимирован. Я также пытался применить это к самому внешнему div, в котором находится этот код, потому что это также изменяется в размере, но это также, похоже, не сработало.

Мой вопрос в том, возможно ли вообще анимировать такие изменения, и если да, может ли кто-нибудь указать мне правильное направление, как это сделать? Заранее спасибо.

Ответ №1:

Переходы CSS не будут работать при переходе от «display: none» к «display: inline». Я бы рекомендовал использовать свойство видимости CSS. Сначала рассмотрите возможность перемещения тегов h3 и p в div.

 function readMore()
{
    if(active == false)
    {
        active = true;
        moreText.style.visibility = "visible";
        moreText.style.maxHeight = "600px";
        button.innerHTML = "Read less";
    }
    else if(active == true)
    {
        active = false;
        //moreText.style.display = "none";
        moreText.style.visibility = "hidden";
        moreText.style.maxHeight = "0";
        button.innerHTML = "Read more";
    }
}  
 <div id="more" style="visibility: hidden; transition: all .5s linear; max-height:0;">
  <h3 style="margin-bottom: 0.3em;">Some hidden text</h3>
  <p>some more hidden text</p>
</div>  

Ответ №2:

Вы можете попробовать использовать классы CSS, что может быть проще.

HTML:

 <body> 
    <h3 >some text</h3>
    <p>some more text</p>
                            
    <span id="more" class='more-container'>
        <h3>Some hidden text</h3>
        <p>some more hidden text</p>
    </span>
    
    <button id="readMore">Read more</button>

</body>
  

Javascript:

 const button = document.getElementById("readMore");
const moreText = document.getElementById("more");

button.addEventListener("click", () => {
    if (moreText.classList.value.includes("active")){
        moreText.classList.remove("active")
        button.classList.remove("button-active")
    } else {
        moreText.classList.add("active")
        button.classList.add("button-active")
    }
})
  

Примечание:

  • Я использовал здесь прослушиватель событий вместо onClick вызова функции, что является моим предпочтением

CSS:

 .more-container {
  display: block;
  opacity: 0;
  visibility: hidden;
}

.active {
  opacity: 1;
  visibility: visible;
  transition: all 0.5s linear;
}

button {
  margin-top: -80px;
  position: relative;
}

.button-active {
  margin-top: 0px;
}
  

Ответ №3:

Отображение: block и none не может иметь перехода, потому что он показывает или скрывает элемент в DOM. Либо мы можем использовать свойство видимости, чтобы плавно отображать и скрывать этот раздел. То же самое было предложено и в других ответах.

Или я бы посоветовал не использовать видимость и использовать max-height с переходом, поскольку это Read More вещь. Таким образом, в идеале он должен расширяться до самого низа при «Показать больше» и сворачиваться при «Показать меньше». Вот фрагмент кода, имитирующий то же поведение:

   <body>
    <h3 style="margin-bottom: 0.3em;">some text</h3>
    <p>some more text</p>

    <span
      id="more"
      style="
        display: block;
        overflow: hidden;
        max-height: 0;
        transition: all 0.3s ease-in;
      "
    >
      <h3 style="margin-bottom: 0.3em;">Some hidden text</h3>
      <p>some more hidden text</p>
    </span>

    <button id="readMore" onclick="readMore()">Read more</button>

    <script>
      var active = false;
      var moreText = document.getElementById("more");
      var button = document.getElementById("readMore");
      moreText.style.overflow = "hidden";

      function readMore() {
        if (active == false) {
          active = true;
          moreText.style.maxHeight = "100px";
          button.innerHTML = "Read less";
        } else if (active == true) {
          active = false;
          moreText.style.maxHeight = 0;
          button.innerHTML = "Read more";
        }
      }
    </script>
  </body>
  

И codesandbox для того же.