Bueno BenM indicó, es necesario detectar la altura de la ventana + la posición de desplazamiento para que coincida con su poisiton superior. La función de su uso está bien y hace el trabajo, aunque es algo más complejo que lo que necesita.
Si usted no utiliza jQuery
entonces el script sería algo como esto:
function posY(elm) {
var test = elm, top = 0;
while(!!test && test.tagName.toLowerCase() !== "body") {
top += test.offsetTop;
test = test.offsetParent;
}
return top;
}
function viewPortHeight() {
var de = document.documentElement;
if(!!window.innerWidth)
{ return window.innerHeight; }
else if(de && !isNaN(de.clientHeight))
{ return de.clientHeight; }
return 0;
}
function scrollY() {
if(window.pageYOffset) { return window.pageYOffset; }
return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}
function checkvisible(elm) {
var vpH = viewPortHeight(), // Viewport Height
st = scrollY(), // Scroll Top
y = posY(elm);
return (y > (vpH + st));
}
Usando jQuery es mucho más fácil:
function checkVisible(elm, evalType) {
evalType = evalType || "visible";
var vpH = $(window).height(), // Viewport Height
st = $(window).scrollTop(), // Scroll Top
y = $(elm).offset().top,
elementHeight = $(elm).height();
if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
if (evalType === "above") return ((y < (vpH + st)));
}
Esto incluso ofrece un segundo parámetro. Con "visible" (o sin segundo parámetro) verifica estrictamente si un elemento está en la pantalla. Si está configurado en "arriba", volverá a ser verdadero cuando el elemento en cuestión esté en o encima de la pantalla.
ver en acción: http://jsfiddle.net/RJX5N/2/
espero que esto responda a su pregunta.
- MEJORADO VERSION--
Esto es mucho más corto y debe hacerlo así:
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}
con un violín para probarlo: http://jsfiddle.net/t2L274ty/1/
y una versión con threshold
y mode
incluido:
function checkVisible(elm, threshold, mode) {
threshold = threshold || 0;
mode = mode || 'visible';
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
var above = rect.bottom - threshold < 0;
var below = rect.top - viewHeight + threshold >= 0;
return mode === 'above' ? above : (mode === 'below' ? below : !above && !below);
}
y con un violín para probarlo: http://jsfiddle.net/t2L274ty/2/
¿Intentó usar 'top' en lugar de offsetTop? – Neal
echa un vistazo a: http://stackoverflow.com/questions/487073/jquery-check-if-element-is-visible-after-scroling – RDL