3

function showhide(id) {
  obj = document.getElementById(id);

  if (obj.style.display == 'none' || obj.style.display == null)
    obj.style.display = 'block';
  else
    obj.style.display = 'none';
}
#stuff {
  display: none;
}
<a href="#" onclick="showhide('stuff'); return false;">Click Me</a>

<div id="stuff">
  secret stuff
</div>

This kinda works but require two clicks. It seems that it can’t detect that the state is null.

Apparently if I change the condition to this it works:

if (obj.style.display == 'block')
        obj.style.display  = 'none';
else
        obj.style.display  = 'block';

My question now is, what is wrong with the first condition?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
IMB
  • 15,163
  • 19
  • 82
  • 140

3 Answers3

1

If the element's display is being specified by a CSS rule, you'll need to get it's computed style. What you're doing would work if you were replacing an inline style on the div.

function showhide (id)
{
    obj = document.getElementById(id);
    var displayStyle = obj.currentStyle ? obj.currentStyle.display :
                          getComputedStyle(obj, null).display;
    if (displayStyle == 'none' || displayStyle == null)
        obj.style.display  = 'block';
    else
        obj.style.display  = 'none';
}
#stuff { display:none; }
<a href="#" onclick="showhide('stuff'); return false;">Click Me</a>

<div id="stuff">
    secret stuff
</div>
Piyush
  • 1,162
  • 9
  • 17
0

Ask yourself: at what point is obj.style.display ever null? If you actually log it to the console, you’ll get "".

In your first code obj.style.display is neither "none" nor "", so the else case is executed: it’ll be set to "none". It already isn’t displayed, but only because of a CSS rule, not a direct style property on the element itself.

Your second code works because it implies that "" and "none" behave the same way and "block" behaves differently, which is actually the case (if you only use "none" and "block").

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
0

You could set the display attribute of the element directly rather than using CSS, so:

<div id="stuff" style="display:none">
  secret stuff
</div>

and get rid of

#stuff { display:none; }

Then your first example (the null check is not needed) would work.

James
  • 20,957
  • 5
  • 26
  • 41