0

Whenever you have an element with its display property set to none, and you try to trigger a transition so that it "fades in", it jumps quickly to full opacity, unless you add a timeout. Do you have any idea of how to get around this? The timeout works, kinda, but not as well as I would like. Here's what I have:

fadeIn: function(speed) {
    var len = this.length,
        speed = speed || '1000',
        transitionString = 'opacity ' + speed + 'ms';
    while (len--) {

        el = this[len]; //*this* is an object containing DOM elements

        (function motherLoop(el, len) {

            setTimeout(function () {

                el.style.display = 'block';

                el.style.transition = transitionString;

                el.style.opacity = 0;    

                //timeout needed for transition to trigger...

                (function babyLoop(el, len) {
                    setTimeout(function () {
                        el.style.opacity = 1;
                        if(len--) babyLoop(el, len);
                    }, 10);
                })(el, len);


                function transitionEnd() {

                    el.removeEventListener('transitionend', transitionEnd);
                    el.style.opacity = '';
                    el.style.transition = '';

                }
                el.addEventListener('transitionend', transitionEnd);
                if(len--) motherLoop(el, len);
            }, 50);

        })(el, len);
    }
    return this;
}  

As you can see, it is really messy code, but so far the timeout has been the only thing I find that works. This only happens if the element has its display set to none, though. And it's sometimes set to none because I have another method that hides given element. As you can see, I first set the (hidden) element to display: block, I add the CSS transition, set its opacity to 0 and then to 1. It is when switching to opacity: 1 that the timeout is crucial for the transition to trigger. Is there anything you can see that I'm doing wrong?

What I'd like to do, specifically, is not rely on the timeouts, because they don't work well (the transition still doesn't trigger sometimes), and because they don't seem "natural". As a side effect, I'd like to learn why this happens, if you could help. Thank you.

1 Answers1

0

Just change display:none; to visibility:hidden; and change it to visibility:visible; with all your other properties (leaving display manipulations out completely) then the browser will get the starting point correctly and the element will fade in instantly without any need of delays. As when you change the display property at the same time as the desired opacity/width/whatever animated changes it will start with those. Then change position accordingly to your needs.

Probably the best way is to handle that with change of classes rather than setting the properties with style property, up to you though.

Jan
  • 689
  • 1
  • 6
  • 22