After all, none of examples suits me, so i wrote my own.
Tests (no support of IE filter:alpha):
a) check if document is not hidden
b) check if element has zero width / height / opacity or display:none / visibility:hidden in inline styles
c) check if the center (also because it faster than test every pixel / corner) of element is not hidden by other element (and all ancestors, example: overflow:hidden / scroll / one element over enother) or screen edges
d) check if element has zero width / height / opacity or display:none / visibility:hidden in computed styles (among all ancestors)
Tested on
Android 4.4 (Native browser/Chrome/Firefox), Firefox (Win/Mac), Chrome (Win/Mac), Opera (Win Presto/Mac Webkit), IE (IE5-11 document modes + IE8 on virtual machine), Safari (Win/Mac/iOS)
var is_visible = (function () { var x = window.pageXOffset ? window.pageXOffset + window.innerWidth - 1 : 0, y = window.pageYOffset ? window.pageYOffset + window.innerHeight - 1 : 0, relative = !!((!x && !y) || !document.elementFromPoint(x, y)); function inside(child, parent) { while(child){ if (child === parent) return true; child = child.parentNode; } return false; }; return function (elem) { if ( document.hidden || elem.offsetWidth==0 || elem.offsetHeight==0 || elem.style.visibility=='hidden' || elem.style.display=='none' || elem.style.opacity===0 ) return false; var rect = elem.getBoundingClientRect(); if (relative) { if (!inside(document.elementFromPoint(rect.left + elem.offsetWidth/2, rect.top + elem.offsetHeight/2),elem)) return false; } else if ( !inside(document.elementFromPoint(rect.left + elem.offsetWidth/2 + window.pageXOffset, rect.top + elem.offsetHeight/2 + window.pageYOffset), elem) || ( rect.top + elem.offsetHeight/2 < 0 || rect.left + elem.offsetWidth/2 < 0 || rect.bottom - elem.offsetHeight/2 > (window.innerHeight || document.documentElement.clientHeight) || rect.right - elem.offsetWidth/2 > (window.innerWidth || document.documentElement.clientWidth) ) ) return false; if (window.getComputedStyle || elem.currentStyle) { var el = elem, comp = null; while (el) { if (el === document) {break;} else if(!el.parentNode) return false; comp = window.getComputedStyle ? window.getComputedStyle(el, null) : el.currentStyle; if (comp && (comp.visibility=='hidden' || comp.display == 'none' || (typeof comp.opacity !=='undefined' && comp.opacity != 1))) return false; el = el.parentNode; } } return true; } })();
How to use:
is_visible(elem) // boolean