views:

97

answers:

5

I'm iterating over a bunch of child nodes and checking to see if they are actually visible on the page with this statement:

if(child.offsetWidth == 0 || child.offsetHeight == 0 || child.style.visibility == 'hidden'     || child.style.display == 'none'){

child is defined in the loop so that's not an issue.

What is an issue is that elements might not have a style attribute defined and so javascript returns "child.style" not defined.

How do I do a seemingly simple if statement like this without it stopping because something is not defined?

I tried doing this:

if(undefined !== child.style){ var addquery = "child.style.visibility == 'hidden' ||     child.style.display == 'none'"; }
if(child.offsetWidth == 0 || child.offsetHeight == 0 || addquery){
console.debug(child);
}

But I think addquery is just evaluating to true and not working.

+4  A: 

If this.child is undefined, the next part between && ( and ) won't be evaluated.

if(child.offsetWidth == 0 || child.offsetHeight == 0 || typeof child.style != 'undefined' && (child.style.visibility == 'hidden' || child.style.display == 'none')){
Lekensteyn
+7  A: 
if(child.offsetWidth == 0 || child.offsetHeight == 0 || (child.style && (child.style.visibility == 'hidden' || child.style.display == 'none')))

Since && is a short-circuit operator, it will only evaluate child.style.visibility == 'hidden' || child.style.display == 'none' if child.style evaluates to true, meaning that child.style exists, and therefore can be accessed. If child.style evaluates to false, the rest will just be ignored; child.style won't be accessed, and therefore no errors will be thrown.

Giu
+2  A: 

Don't use undefined as a keyword, because it doesn't exist in JavaScript.

However, because every variable initially is undefined then testing against a non-existent undefined variable does often work. However:

var undefined = 5; // this could be anywhere in the code

// [...]

if(foo === undefined) // *not* the test you want to be checking

Instead, use typeof foo == "undefined". Only an actually undefined variable will return the string "undefined" from the typeof operator

Gareth
Not quite. `undefined` always exists, since it is defined as a property of the global object, with a value of `undefined`. If `undefined` really didn't exist, `if ("foo" == undefined) {}` would throw a `ReferenceError`. There is a big difference between a variable never having been declared and one that has been declared but has a value of `undefined`. However, you're correct that `undefined` can be assigned to and is therefore unreliable.
Tim Down
Something cool is the way that jQuery gets its hands on `undefined`: `(function( window, undefined ) { /* 6000 lines */ })(window);`
jleedev
+1  A: 

Check the nodeType property of each child. If the child is an element, it is guaranteed to have a style property and there's no need to check whether it's undefined. Your code makes it clear that it's only elements that you're interested in, so you should make sure you only deal with elements.

if ((child.nodeTye == 1) && [...all the other conditions...]) {...}

Also, checking the display and visibility properties of an element's style property won't tell you whether the element is actually visible on the page or not, since the style object only conatins values set explictly on the element via the style attribute or the style property. You need to check the computed value of display and visibility instead, which you can do with window.getComputedStyle (or the element's currentStyle property in IE).

Tim Down
A: 

If you don't want your code to be stopped because of an error (like x.style.display with x.style undefined will trigger an exception), but your code could keep going, just use a try catch

   try {
        ...child.style.visibility...
   } catch(e) {
        // do either nothing or set child.style for instance
   }

this way the code is not stopped, you have a way to catch a problem, and also a way to fix it.

ring0