In the past we used the CSS attribute "display" to show and hide DOM elements. To check if an element is visible, we could just use:
element.offsetWidth > 0
Since we had some problems with Flash and Java Applets (they stop when they get display:none) we switched to the CSS attribute "visibility".
I am now looking for a fast and easy way to check if an element is not visible.
I have tried the following:
- Checking the attribute itself on the element and and all parents => too slow
- Checking the calculated style directly from the browser (element.currentStyle or window.getComputedStyle() plus getPropertyValue(style property)) => also too slow
Do you know any other way or shortcut to see if an element is visible?
In the past we used the CSS attribute "display" to show and hide DOM elements. To check if an element is visible, we could just use:
element.offsetWidth > 0
Since we had some problems with Flash and Java Applets (they stop when they get display:none) we switched to the CSS attribute "visibility".
I am now looking for a fast and easy way to check if an element is not visible.
I have tried the following:
- Checking the attribute itself on the element and and all parents => too slow
- Checking the calculated style directly from the browser (element.currentStyle or window.getComputedStyle() plus getPropertyValue(style property)) => also too slow
Do you know any other way or shortcut to see if an element is visible?
Share Improve this question asked Aug 12, 2009 at 9:57 Jonathan WeissJonathan Weiss 6741 gold badge6 silver badges9 bronze badges 6- I suppose just storing the state in a variable somewhere and updating it every time you change the visibility is out of the question... – Greg Commented Aug 12, 2009 at 10:00
- not really an answer but you could check the source code of some JS libraries like jQuery or mooTools to see how they do it. – Darko Commented Aug 12, 2009 at 10:07
- @Greg: you are correct - this would be too much overhead. You have to update all children of an element when it gets changed... @Darko Z: I already looked at jQuery, but I will check mooTools now... – Jonathan Weiss Commented Aug 12, 2009 at 10:35
- Why do you consider your alternatives to be too slow? – Gumbo Commented Aug 12, 2009 at 10:37
- @Gumbo: it is too slow, because we are talking about hundreds of elements which are checked during the lifetime of a web application. I don't need this check for just a website, but for an AJAX framework: qooxdoo – Jonathan Weiss Commented Aug 12, 2009 at 10:49
6 Answers
Reset to default 8use JQuery and the you can do this
var isVisible = $('#foo').is(':visible');
Remember that visibility:hidden makes an element hidden, but that element still occupies its space, which may have some unexpected consequences on the layout (it may be an advantage as well if you are aware of this).
I would use absolute positioning to move the element far to the left, outside possible screen width. This gets the element out of the flow so the hidden element has no impact on layout, makes the element practically invisible, and it doesn't have the disatvantages of display:none.
.hide {
position:absolute;
left:-3000px;
}
Then to determine if an element is hidden you can use its offsetLeft property:
if( myElement.offsetLeft < 0 ){ /* it's hidden */ }
If you need to determine if a child element is off the screen (you don't know if it's the hidden element or its child) you can use .offsetParent and a while loop, as described in PPK's Find Position article.
Toggling Element Visibility by Kent is an unobtrusive, semantically valid way of presenting content that will degrade nicely for non-CSS-aware browsers.
- After the page loads pletely, we crawl through the entire document tree and look for block-level elements styled with class name toggle. If we find one that says toggle closed, we immediately hide its next sibling element, by styling it with class name hidden.
- When we find one, we tell it to listen for mouse clicks.
- When one of our pet elements hears a click, it leaps into action, hiding (or showing) its next available sibling, the same way we did it during the initial crawl.
- All three class names (toggle, closed, and hidden) are fed in at the bottom in the init call, and may be changed to any valid class name.
Also look at this DevX article which pares the Display and Visibility properties.
Checking the focus would work, either parent is visible or not.
var isVisible = true;
try{
document.getElementById("target").focus();
}catch(err){
isVisible = false;
}
It obviously should work on input or link, but for other element, I'm not sure.
I have studied the same problem before using jQuery, but that time my aim is to focus the first availabe field on a form. The resulting code is like:
$(":text:visible:enabled").filter(function(){
return $(this).parents.filter(function(){
return this.style.display == "none";
}).size()==0;
}).slice(0,1).focus();
It would also work for hidden/invisble parent.
CSS selectors are optimised to find sets of matching elements. There are several libraries implementing this functionality. JQuery, ExtJS Core to name a couple.
Using Ext Core, I could write a javascript function that checks for visibility as follows:
// Checks whether the element is currently visible using
// both visibility and display properties
if(Ext.get(el).isVisible()){
alert('it\'s visible');
};
see http://extjs./products/extcore/docs/?class=Ext.Element for more Ext Core Ext.Element functionality.
function isVisible(elem) {
return elem.style.visibility !== "hidden";
}