534

Using .fadeIn() and .fadeOut(), I have been hiding/showing an element on my page, but with two buttons, one for hide and one for show. I now want to have one button to toggle both.

My HTML / JavaScript as it is:

<a onclick="showTestElement()">Show</a>
<a onclick="hideTestElement()">Hide</a>
function showTestElement() {
  $('#testElement').fadeIn('fast');
}

function hideTestElement() {
  $('#testElement').fadeOut('fast');
}

My HTML / JavaScript as I would like to have it:

<a onclick="toggleTestElement()">Show/Hide</a>
function toggleTestElement() {
  if (document.getElementById('testElement').***IS_VISIBLE***) {
    $('#testElement').fadeOut('fast');
  } else {
    $('#testElement').fadeIn('fast');
  }
}

How do I detect if the element is visible or not?

daaawx
  • 2,268
  • 2
  • 12
  • 13
TheCarver
  • 18,072
  • 24
  • 91
  • 146

3 Answers3

762

You're looking for:

.is(':visible')

Although you should probably change your selector to use jQuery considering you're using it in other places anyway:

if($('#testElement').is(':visible')) {
    // Code
}

It is important to note that if any one of a target element's parent elements are hidden, then .is(':visible') on the child will return false (which makes sense).

jQuery 3

:visible has had a reputation for being quite a slow selector as it has to traverse up the DOM tree inspecting a bunch of elements. There's good news for jQuery 3, however, as this post explains (Ctrl + F for :visible):

Thanks to some detective work by Paul Irish at Google, we identified some cases where we could skip a bunch of extra work when custom selectors like :visible are used many times in the same document. That particular case is up to 17 times faster now!

Keep in mind that even with this improvement, selectors like :visible and :hidden can be expensive because they depend on the browser to determine whether elements are actually displaying on the page. That may require, in the worst case, a complete recalculation of CSS styles and page layout! While we don’t discourage their use in most cases, we recommend testing your pages to determine if these selectors are causing performance issues.


Expanding even further to your specific use case, there is a built in jQuery function called $.fadeToggle():

function toggleTestElement() {
    $('#testElement').fadeToggle('fast');
}
Community
  • 1
  • 1
Bojangles
  • 91,543
  • 47
  • 160
  • 197
  • Can you use this property to call a function as soon as an element becomes visible? – Anderson Green Apr 03 '13 at 02:29
  • Do you know if this will work if the parent is not visible, because technically, if the parent isn't visible then the element isn't visible. – Philll_t Aug 19 '13 at 23:20
  • 3
    @Felipe According to [thise page](http://blog.jquery.com/2009/02/20/jquery-1-3-2-released/#:visible.2F:hidden_Overhauled) **... an element is visible if its browser-reported offsetWidth or offsetHeight is greater than 0**. [This JSBin](http://jsbin.com/UTomiLe/1/edit) shows that if a parent is hidden so are it's children – Bojangles Aug 20 '13 at 08:01
  • 1
    why jQuery whyyyy :( this is not very performance-wise if you have hundreds of elements to check on every scroll event...a direct JS approach would be better. – vsync Mar 30 '14 at 14:18
  • 9
    @vsync Instead of moaning, post a vanilla JavaScript solution that supports IE7 and above. It'll do more to help than posting snarky (albeit correct) comments – Bojangles Mar 30 '14 at 15:22
  • Here is my code for this question http://stackoverflow.com/a/22969337/2274995 – Aleko Apr 09 '14 at 17:12
  • well this fails if parent has `visibility:hidden` set to it. – vsync Apr 22 '14 at 19:17
  • what is diference between object.style.visibility vs is(":visible") – M K Apr 20 '18 at 04:13
47

There's no need, just use fadeToggle() on the element:

$('#testElement').fadeToggle('fast');

Here's a demo.

Ry-
  • 199,309
  • 51
  • 404
  • 420
  • 15
    This is one of those tricky answers, where the question clearly asks one thing, but the best approach for the OP specifically is another. – Jared Farrish Jan 07 '12 at 23:51
30
if($('#testElement').is(':visible')){
    //what you want to do when is visible
}
Ivan Castellanos
  • 7,234
  • 1
  • 39
  • 39