0

I'm trying to hide/show elements using JavaScript. Used code from a similar question as reference. Fade out is working like it should, but for some reason, fade in isn't:

function hidePages() {
  var pages = document.getElementsByClassName('page');
  for(var i = 0; i < pages.length; i++) {
    current = pages[i];
    current.style.opacity = 0;
    setTimeout(function(current) {
      current.style.display = 'none';
    }, 500, current);
  }
}

function navigate(page) {
  hidePages();
  var current = document.getElementById(page);
  setTimeout(function(current) {
    current.style.display = 'block';
    current.style.opacity = 1;
  }, 500, current);
}
.page {
  opacity: 1;
  -webkit-transition: opacity 0.5s;
  -o-transition: opacity 0.5s;
  transition: opacity 0.5s;
}
<a href="#" onclick="navigate('page1')">1</a> 
<a href="#" onclick="navigate('page2')">2</a> 
<a href="#" onclick="navigate('page3')">3</a>
<div class="page" id="page1">Page 1</div>
<div class="page" id="page2" style="display: none">Page 2</div>
<div class="page" id="page3" style="display: none">Page 3</div>        

JSFiddle: https://jsfiddle.net/z2svo5uu/

As you can see, as soon as the element has faded out, it shows up immediately. I want to have the fade transition for fading in too, though.

I know I could do this easier with jQuery, but I'm just wondering why the transition isn't working as it should? Anyone know?

1
  • just increase the value in timeout in case of fade in Commented Feb 8, 2018 at 13:08

1 Answer 1

1

You are facing an asynchrony issue, because the way you've written your code, both timeouts, inside hidePages and navigate, run at about the same time and it's not standard which will be executed first, because the timeout value is always approximated. Sometimes, a timeout set to 500ms could be executed after 496ms or 503ms.

Also, try using a nested timeout inside your current one in navigate to separate the change in display with the change in opacity. Something in the range of 1-10ms will work fine to ensure the animation runs smoothly.

Snippet:

function hidePages() {
  var pages = document.getElementsByClassName('page');
  for (var i = 0; i < pages.length; i++) {
    current = pages[i];
    current.style.opacity = 0;
    setTimeout(function(current) {
      current.style.display = 'none';
    }, 500, current);
  }
}

function navigate(page) {
  hidePages();
  var current = document.getElementById(page);
  setTimeout(function(current) {
    current.style.display = 'block';
    setTimeout(function(current) {
      current.style.opacity = 1;
    }, 10, current);
  }, 500, current);
}
.page {
  opacity: 1;
  -webkit-transition: opacity 0.5s;
  -o-transition: opacity 0.5s;
  transition: opacity 0.5s;
}
<a href="#" onclick="navigate('page1')">1</a>
<a href="#" onclick="navigate('page2')">2</a>
<a href="#" onclick="navigate('page3')">3</a>
<div class="page" id="page1">Page 1</div>
<div class="page" id="page2" style="display: none">Page 2</div>
<div class="page" id="page3" style="display: none">Page 3</div>

Sign up to request clarification or add additional context in comments.

3 Comments

it is same as in his jsfiddle
Thanks! Still confused as to why that solved the issue. Guess it's a JS thing. lol
You have to synchronise your time outs correctly @Besasam. The timeouts inside hidePages and navigate are executed both after 500ms and it's not standard which will work first each time. Make sure to use some extra milliseconds as margin to ensure the timeout inside hidePages runs first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.