Put smooth transition with Javascript

Asked

Viewed 1,230 times

0

I created an expandable div with Javascript, but I would like it to open more smoothly. How could I add a Transition to that? Follows the code:

TS:

toggleDiv(divid){
    if(document.getElementById(divid).style.display == 'none'){
      document.getElementById(divid).style.display = 'block';

    }else{
      document.getElementById(divid).style.display = 'none';
    }

  }

HTML:

 <ion-card (click)="toggleDiv('minha-div-1');">
    <ion-card-content>
Projeto:
        <div id="minha-div-1" style="display:none">
        <h3>This is a test!<br>Can you see me?</h3>
        </div>

    </ion-card-content>
  </ion-card>
  • 1

    Your problem is that you used display, and display has no middle ground, either is or is not on screen. Vc can replace by display by opacity which should work

4 answers

0

Looking at the answers, the big problem is that using only opacity: 0, a lot of things escapes, because the element is not visible, but it is still there, that is, it remains selectable, "clickable", occupying the space and doing everything it would do without opacity, simply interacting with the "invisible" area".

To solve this problem is very simple, just along with the opacity: 0, include pointer-events: none; user-select: none; z-index: -1.

Example I:

Without changing the element size

const span = document.querySelector('span');
const button = document.querySelector('button');
const exemplo = () => span.classList.toggle('transition');
button.addEventListener('click', exemplo);
/* Estado padrão */
span {
  
  -webkit-transition: opacity 500ms;
  -o-transition: opacity 500ms;
  transition: opacity 500ms;
  
  /* IGNORE */
  display: block;
}

.transition {
  
  pointer-events: none;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  z-index: -1;
  opacity: 0;
}

/* IGNORE */
div {
  border: 1px solid black;
  padding: 10px;
  text-align: center;
}
<div>
  <span>Sem modificar o tamanho do elemento</span>
  <button>Testar</button>
</div>

When you want the spacing also to be corrected by hiding the element and, also with the transition, you can put a height static using only CSS or dynamic, with JS.

Example II:

Changing the size of the element

const span = document.querySelector('span');
const span_height = span.clientHeight;
const button = document.querySelector('button');
const exemplo = () => {

    span.classList.toggle('transition');
  span.style.height = !span.classList.contains('transition') ? `${span_height}px` : 0;
}

span.style.height = `${span_height}px`; // garante a transição na primeira chamada
button.addEventListener('click', exemplo);
/* Estado padrão */
span {
  
  -webkit-transition: opacity 400ms, height 500ms;
  -o-transition: opacity 400ms, height 500ms;
  transition: opacity 400ms, height 500ms;
  
  /* IGNORE */
  display: block;
}

.transition {
  
  pointer-events: none;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  opacity: 0;
  z-index: -1;
  overflow: hidden;
}

/* IGNORE */
div {
  border: 1px solid black;
  padding: 10px;
  text-align: center;
}
<div>
  <span>Modificando o tamanho do elemento</span>
  <button>Testar</button>
</div>

  • Note that in neither of the two examples, it is possible to interact with the elements while hidden.

0

Experiment with opacity

function toggleDiv(){

  let div = document.getElementById('minha-div-1');

  div.classList.toggle('hide');

}
.minha-div{
  opacity: 1;
  transition: opacity 1s ease-out;
}

.minha-div.hide{
  opacity: 0; 
  transition: opacity 1s ease-out;
}
<button type="button" onclick="toggleDiv();">Click Me!</button>
<div id="minha-div-1" class="minha-div">
  <h3>This is a test!<br>Can you see me?</h3>
</div>

  • in this case I do the manipulation by own css ?

0

With Javascript you can use setInterval() changing the property opacity:

function toggleDiv(divid){

   var el = document.getElementById(divid);
   var transicao, t;
   clearInterval(transicao);

   if(el.style.display == 'none'){
      el.style.opacity = "0";
      el.style.display = 'block';
      var x = .1;
    }else{
      var x = .9;
      t = true;
    }

   transicao = setInterval(function(){
      el.style.opacity = x;
      x+= t ? -.1 : .1;
      if( (x >= 1 && !t) || (x <= 0 && t)){
         clearInterval(transicao);
         if(x <= 0) el.style.display = 'none';
      }
   }, 50);

}
<div onclick="toggleDiv('minha-div-1');">
 <ion-card-content>
Projeto (clique aqui):
     <div id="minha-div-1" style="display:none">
     <h3>This is a test!<br>Can you see me?</h3>
     </div>

 </ion-card-content>
</div>

0

Can have the same result using only html + css:

input { display: none}

h3 {
  opacity: 0;
  transition: opacity 500ms ease-in
}

input:checked + h3 {
  opacity: 1
}
<label for='toggle'>Click</label>
<input type='checkbox' id='toggle'>

<h3>This is a test!<br>Can you see me?</h3>

  • but that way if it’s more of an option, it doesn’t push down, it goes up

  • Huh? To add more items just have one id own. If there are particularities, edit your question and include these details The way the question is at the moment, the only particularity is to display/hide an element "smoothly".

  • I guess you didn’t read that it is written with "Javascript" in the title, with css if there is another item below it sobescreve, with javascript it pushes down the item.

  • 1

    I understand. But responses in stackoverflow tend to solve a problem in a generic way and not be support for solving the your problem in specific, why I left my alternative. And about Javascript, take a read on style that you’re using. What you’re "moving down" is not because it’s JS or CSS, but because it’s using display.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.