0

I have an on-hover menu which has to have display:none while it's not in use, so you can click things under it.

When it time to open it up, I turn the display to inline-block; and then fade in the opacity using css transition - with this code:

elm.onmouseover = function(){
    menu.style.display = "inline-block";
    menu.style.opacity = 1;
};

When this code does run, the element pops straight in without any fade.

My theory was that the javascript runs so fast that the element hasn't changed display type by the time the opacity change kicks in, so I did this:

elm.onmouseover = function(){
    menu.style.display = "inline-block";
    for (var i=1000...; i--; );
    menu.style.opacity = 1;
};

It now visibly waits; however, still pops in without a fade.

I went into my console and ran:

menu.style.display = "inline-block";
menu.style.opacity = 1; // run
> return message

and it didnt work; however, when I split the statements into two like this

menu.style.display = "inline-block"; // run
> return message

menu.style.opacity = 1; // run
> return message

It works fine, and the delay between the two is much less than the one caused by the for loop.

What is the root of this behaviour? I'm baffled.

  • Well, unless you've actually written a function that does animations, and they can be somewhat complicated with timers and everything, or you're using CSS animations, just setting the opacity to something else isn't going to fade at all, it just ... wait for it .... changes the opacity. – adeneo Oct 08 '16 at 19:13
  • I obviusly have transitions in place... –  Oct 08 '16 at 19:18
  • 2
    It's not obvious, as we can't see them. – adeneo Oct 08 '16 at 19:26
  • 1
    Can you add a demo in [jsfiddle.net](http://jsfiddle.net) or equivalent? – Esteban Gerpe Oct 08 '16 at 19:28

2 Answers2

0

DOM only refreshes once your entire code finishes, because it's sync with main-thread.

If you just wait a 1ms with a setTimeout, what you're expecting, will work:

elm.onmouseover = function () {
   menu.style.display = 'inline-block';
   setTimeout(function () {
       menu.style.opacity = 1;
   }, 1);
}

https://jsfiddle.net/vtd3y5ug/

Edmundo Santos
  • 8,006
  • 3
  • 28
  • 38
  • Thank you for actual answer, it make's sense now. I did however end up using `visibility` instead, how come's that one works? It's used in the exact same fashion but updates. –  Oct 08 '16 at 20:57
  • See: http://stackoverflow.com/questions/133051/what-is-the-difference-between-visibilityhidden-and-displaynone Display: none, means that the element isn't on the page. Visibility: hidden, means the element is on the page, but is not visible. – Edmundo Santos Oct 08 '16 at 21:05
-1

You can't use display: none with opacity for fade effect.

Instead of display: none and display: inline-block use visibility: hidden and visibility: visible.