una tiene saber obtener elemento clase atributo javascript html firefox dom

javascript - tiene - ¿Cómo saber si un elemento DOM es visible en la ventana gráfica actual?



saber si un elemento es visible javascript (22)

Actualizar

En los navegadores modernos, es posible que desee revisar la API de Intersection Observer que ofrece los siguientes beneficios:

  • Mejor rendimiento que escuchar eventos de desplazamiento.
  • Trabaja en iframes de dominios cruzados
  • Puede decir si un elemento está obstruyendo / intersectando a otro.

Intersection Observer está en camino de ser un estándar completo y ya es compatible con Chrome 51+, Edge 15+ y Firefox 55+ y está en desarrollo para Safari. También hay un polyfill disponible.

Respuesta anterior

Hay algunos problemas con la respuesta proporcionada por Dan que podrían convertirlo en un enfoque inadecuado para algunas situaciones. Algunos de estos problemas se señalan en su respuesta cerca del final, que su código dará falsos positivos para elementos que son:

  • Oculto por otro elemento frente al que está siendo probado.
  • Fuera del área visible de un elemento padre o ancestro
  • Un elemento o sus hijos ocultos usando la propiedad de clip CSS

Estas limitaciones se demuestran en los siguientes resultados de una prueba simple :

La solución: isElementVisible()

Aquí hay una solución a esos problemas, con el resultado de la prueba a continuación y una explicación de algunas partes del código.

function isElementVisible(el) { var rect = el.getBoundingClientRect(), vWidth = window.innerWidth || doc.documentElement.clientWidth, vHeight = window.innerHeight || doc.documentElement.clientHeight, efp = function (x, y) { return document.elementFromPoint(x, y) }; // Return false if it''s not in the viewport if (rect.right < 0 || rect.bottom < 0 || rect.left > vWidth || rect.top > vHeight) return false; // Return true if any of its four corners are visible return ( el.contains(efp(rect.left, rect.top)) || el.contains(efp(rect.right, rect.top)) || el.contains(efp(rect.right, rect.bottom)) || el.contains(efp(rect.left, rect.bottom)) ); }

Pasando la prueba: http://jsfiddle.net/AndyE/cAY8c/

Y el resultado:

Notas adicionales

Sin embargo, este método no está exento de limitaciones. Por ejemplo, un elemento que se está probando con un índice z más bajo que otro elemento en la misma ubicación se identificará como oculto incluso si el elemento en frente no oculta ninguna parte de él. Aún así, este método tiene sus usos en algunos casos que la solución de Dan no cubre.

Tanto element.getBoundingClientRect() como document.elementFromPoint() forman parte de la especificación del borrador de trabajo de CSSOM y son compatibles con al menos IE 6 y posteriores y la mayoría de los navegadores de escritorio durante un tiempo prolongado (aunque no perfectamente). Ver Quirksmode en estas funciones para más información.

contains() se utiliza para ver si el elemento devuelto por document.elementFromPoint() es un nodo secundario del elemento que estamos probando para la visibilidad. También devuelve true si el elemento devuelto es el mismo elemento. Esto solo hace que el cheque sea más robusto. Es compatible con todos los principales navegadores, siendo Firefox 9.0 el último de ellos en agregarlo. Para soporte de Firefox más antiguo, verifique el historial de esta respuesta

Si desea probar más puntos alrededor del elemento para la visibilidad, es decir, para asegurarse de que el elemento no esté cubierto por más del 50%, por ejemplo, no se necesitaría mucho para ajustar la última parte de la respuesta. Sin embargo, tenga en cuenta que probablemente sería muy lento si verificara cada píxel para asegurarse de que era 100% visible.

¿Hay una manera eficiente de saber si un elemento DOM (en un documento HTML) está actualmente visible (aparece en la ventana gráfica )?

(La pregunta se refiere a Firefox)


Ahora la mayoría de los navegadores admiten el método getBoundingClientRect , que se ha convertido en la mejor práctica. El uso de una respuesta antigua es muy lento , no es preciso y tiene varios errores .

La solución seleccionada como correcta casi nunca es precisa . Puedes leer más sobre sus errores.

Esta solución se probó en IE7 +, iOS5 + Safari, Android2 +, Blackberry, Opera Mobile e IE Mobile 10 .

function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery === "function" && el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ ); }

Cómo utilizar:

Puede estar seguro de que la función dada anteriormente devuelve la respuesta correcta en el momento en que se llama, pero ¿qué sucede con la visibilidad del elemento de seguimiento como un evento?

Coloque el siguiente código en la parte inferior de su etiqueta <body> :

function onVisibilityChange(el, callback) { var old_visible; return function () { var visible = isElementInViewport(el); if (visible != old_visible) { old_visible = visible; if (typeof callback == ''function'') { callback(); } } } } var handler = onVisibilityChange(el, function() { /* your code go here */ }); //jQuery $(window).on(''DOMContentLoaded load resize scroll'', handler); /* //non-jQuery if (window.addEventListener) { addEventListener(''DOMContentLoaded'', handler, false); addEventListener(''load'', handler, false); addEventListener(''scroll'', handler, false); addEventListener(''resize'', handler, false); } else if (window.attachEvent) { attachEvent(''onDOMContentLoaded'', handler); // IE9+ :( attachEvent(''onload'', handler); attachEvent(''onscroll'', handler); attachEvent(''onresize'', handler); } */

Si realiza alguna modificación de DOM, pueden cambiar la visibilidad de su elemento, por supuesto.

Directrices y errores comunes:

Tal vez usted necesita hacer un seguimiento de la página zoom / pinch dispositivo móvil? jQuery debe manejar zoom/pinch navegador de zoom/pinch cruzado, de lo contrario, el first o second enlace lo ayudarán.

Si modifica DOM , puede afectar la visibilidad del elemento. Debes tomar el control de eso y llamar al handler() manualmente. Desafortunadamente, no tenemos ningún evento de onrepaint cruzada del navegador. Por otro lado, eso nos permite realizar optimizaciones y volver a verificar solo las modificaciones de DOM que pueden cambiar la visibilidad del elemento.

Nunca lo utilice nunca solo dentro de jQuery $(document).ready() , porque no hay garantía de que CSS se haya aplicado en este momento. Su código puede funcionar localmente con su CSS en el disco duro, pero una vez que se coloque en un servidor remoto, fallará.

Una DOMContentLoaded se ha DOMContentLoaded , se aplican los estilos , pero las imágenes aún no se han cargado . Por lo tanto, debemos agregar window.onload event listener.

No podemos atrapar el evento zoom / pinch todavía.

El último recurso podría ser el siguiente código:

/* TODO: this looks like a very bad code */ setInterval(handler, 600);

Puede usar la impresionante característica de la API HTML5 de la página si le importa si la pestaña con su página web está activa y visible.

TODO: este método no maneja dos situaciones:


Aquí está mi solución, funcionará si un elemento está oculto dentro de un contenedor con capacidad de desplazamiento.

Aquí hay una demostración (intente cambiar el tamaño de la ventana para)

var visibleY = function(el){ var top = el.getBoundingClientRect().top, rect, el = el.parentNode; do { rect = el.getBoundingClientRect(); if (top <= rect.bottom === false) return false; el = el.parentNode; } while (el != document.body); // Check its within the document viewport return top <= document.documentElement.clientHeight; };

Solo necesitaba comprobar si está visible en el eje Y (para una función de carga de más registros de ajax).


Aquí hay una función que indica si un elemento está visible en la ventana gráfica actual de un elemento principal :

function inParentViewport(el, pa) { if (typeof jQuery === "function"){ if (el instanceof jQuery) el = el[0]; if (pa instanceof jQuery) pa = pa[0]; } var e = el.getBoundingClientRect(); var p = pa.getBoundingClientRect(); return ( e.bottom >= p.top && e.right >= p.left && e.top <= p.bottom && e.left <= p.right ); }


Basándome en la solución de @dan anterior ( https://.com/a/7557433/5628 ), intenté limpiar la implementación para que usarla varias veces en la misma página sea más fácil:

$(function() { $(window).on(''load resize scroll'', function() { addClassToElementInViewport($(''.bug-icon''), ''animate-bug-icon''); addClassToElementInViewport($(''.another-thing''), ''animate-thing''); // 👏 repeat as needed ... }); function addClassToElementInViewport(element, newClass) { if (inViewport(element)) { element.addClass(newClass); } } function inViewport(element) { if (typeof jQuery === "function" && element instanceof jQuery) { element = element[0]; } var elementBounds = element.getBoundingClientRect(); return ( elementBounds.top >= 0 && elementBounds.left >= 0 && elementBounds.bottom <= $(window).height() && elementBounds.right <= $(window).width() ); } });

La forma en que lo estoy usando es que cuando el elemento se desplaza a la vista, estoy agregando una clase que activa una animación de fotograma clave css. Es bastante sencillo y funciona especialmente bien cuando tienes como 10 o más cosas para animar condicionalmente en una página.

¡Espero eso ayude!


Como servicio público:
La respuesta de Dan con los cálculos correctos (el elemento puede ser> la ventana, especialmente en las pantallas de los teléfonos móviles) y las pruebas de jQuery correctas, además de agregar isElementPartiallyInViewport:

Por cierto, la difference entre window.innerWidth y document.documentElement.clientWidth es que clientWidth / clientHeight no incluye la barra de desplazamiento, mientras que window.innerWidth / Height sí lo hace.

function isElementPartiallyInViewport(el) { //special bonus for those using jQuery if (typeof jQuery !== ''undefined'' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 } var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); // http://.com/questions/325933/determine-whether-two-date-ranges-overlap var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0); var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0); return (vertInView && horInView); } // http://.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery !== ''undefined'' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); return ( (rect.left >= 0) && (rect.top >= 0) && ((rect.left + rect.width) <= windowWidth) && ((rect.top + rect.height) <= windowHeight) ); } function fnIsVis(ele) { var inVpFull = isElementInViewport(ele); var inVpPartial = isElementPartiallyInViewport(ele); console.clear(); console.log("Fully in viewport: " + inVpFull); console.log("Partially in viewport: " + inVpPartial); }

Caso de prueba

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>Test</title> <!-- <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script src="scrollMonitor.js"></script> --> <script type="text/javascript"> function isElementPartiallyInViewport(el) { //special bonus for those using jQuery if (typeof jQuery !== ''undefined'' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 } var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); // http://.com/questions/325933/determine-whether-two-date-ranges-overlap var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0); var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0); return (vertInView && horInView); } // http://.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery !== ''undefined'' && el instanceof jQuery) el = el[0]; var rect = el.getBoundingClientRect(); var windowHeight = (window.innerHeight || document.documentElement.clientHeight); var windowWidth = (window.innerWidth || document.documentElement.clientWidth); return ( (rect.left >= 0) && (rect.top >= 0) && ((rect.left + rect.width) <= windowWidth) && ((rect.top + rect.height) <= windowHeight) ); } function fnIsVis(ele) { var inVpFull = isElementInViewport(ele); var inVpPartial = isElementPartiallyInViewport(ele); console.clear(); console.log("Fully in viewport: " + inVpFull); console.log("Partially in viewport: " + inVpPartial); } // var scrollLeft = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft, // var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; </script> </head> <body> <div style="display: block; width: 2000px; height: 10000px; background-color: green;"> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <input type="button" onclick="fnIsVis(document.getElementById(''myele''));" value="det" /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <div style="background-color: crimson; display: inline-block; width: 800px; height: 500px;" ></div> <div id="myele" onclick="fnIsVis(this);" style="display: inline-block; width: 100px; height: 100px; background-color: hotpink;"> t </div> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <br /><br /><br /><br /><br /><br /> <input type="button" onclick="fnIsVis(document.getElementById(''myele''));" value="det" /> </div> <!-- <script type="text/javascript"> var element = document.getElementById("myele"); var watcher = scrollMonitor.create( element ); watcher.lock(); watcher.stateChange(function() { console.log("state changed"); // $(element).toggleClass(''fixed'', this.isAboveViewport) }); </script> --> </body> </html>


Comprueba si el elemento está al menos parcialmente a la vista (dimensión vertical):

function inView(element) { var box = element.getBoundingClientRect(); return inViewBox(box); } function inViewBox(box) { return ((box.bottom < 0) || (box.top > getWindowSize().h)) ? false : true; } function getWindowSize() { return { w: document.body.offsetWidth || document.documentElement.offsetWidth || window.innerWidth, h: document.body.offsetHeight || document.documentElement.offsetHeight || window.innerHeight} }


Creo que esta es una forma más funcional de hacerlo. La respuesta de Dan no funciona en un contexto recursivo.

Esta función resuelve el problema cuando su elemento se encuentra dentro de otros divs desplazables mediante la prueba de cualquier nivel recursivamente superior a la etiqueta HTML, y se detiene en el primer falso.

/** * fullVisible=true only returns true if the all object rect is visible */ function isReallyVisible(el, fullVisible) { if ( el.tagName == "HTML" ) return true; var parentRect=el.parentNode.getBoundingClientRect(); var rect = arguments[2] || el.getBoundingClientRect(); return ( ( fullVisible ? rect.top >= parentRect.top : rect.bottom > parentRect.top ) && ( fullVisible ? rect.left >= parentRect.left : rect.right > parentRect.left ) && ( fullVisible ? rect.bottom <= parentRect.bottom : rect.top < parentRect.bottom ) && ( fullVisible ? rect.right <= parentRect.right : rect.left < parentRect.right ) && isReallyVisible(el.parentNode, fullVisible, rect) ); };


Depende de lo que entiendas por visible. Si quiere decir que se muestra actualmente en la página, dada la posición de desplazamiento, puede calcularlo en función de los elementos y desplazamiento y la posición de desplazamiento actual.


Encontré preocupante que no hubiera una versión centrada en jQuery de la funcionalidad disponible. Cuando me topé con la solución de Dan, tuve la oportunidad de ofrecer algo a las personas que les gusta programar en el estilo jQuery OO. Asegúrese de desplazarse hacia arriba y dejar un voto positivo en el código de Dan. Es agradable y ágil y funciona como un encanto para mí.

bada bing bada boom

$.fn.inView = function(){ if(!this.length) return false; var rect = this.get(0).getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; //additional examples for other use cases //true false whether an array of elements are all in view $.fn.allInView = function(){ var all = []; this.forEach(function(){ all.push( $(this).inView() ); }); return all.indexOf(false) === -1; }; //only the class elements in view $(''.some-class'').filter(function(){ return $(this).inView(); }); //only the class elements not in view $(''.some-class'').filter(function(){ return !$(this).inView(); });

uso

$(window).on(''scroll'',function(){ if( $(''footer'').inView() ) { // do cool stuff } });


Hay un complemento de jQuery llamado inview que hace el trabajo


Intenté la respuesta de Dan, pero el álgebra utilizada para determinar los límites es incorrecta. La respuesta de ryanve es más cercana, pero el elemento que se está probando debe estar dentro de la ventana gráfica por al menos 1 píxel, así que pruebe esta función:

function isElementInViewport(el) { var rect = el.getBoundingClientRect(); return rect.bottom > 0 && rect.right > 0 && rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ && rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */; }


La solución fácil y pequeña que me ha funcionado.

Ejemplo Desea ver si el elemento es visible en el elemento principal que tiene desplazamiento de desbordamiento.

$(window).on(''scroll'', function () { var container = $(''#sidebar''); var containerHeight = container.height(); var scrollPosition = $(''#row1'').offset().top - container.offset().top; if (containerHeight < scrollPosition) { console.log(''not visible''); } else { console.log(''visible''); } })


Me parece que la respuesta aceptada aquí es demasiado complicada para la mayoría de los casos de uso. Este código hace el trabajo bien (usando JQuery) y diferencia entre elementos totalmente visibles y parcialmente visibles.

var element = $("#element"); var topOfElement = element.offset().top; var bottomOfElement = element.offset().top + element.outerHeight(true); var $window = $(window); $window.bind(''scroll'', function() { var scrollTopPosition = $window.scrollTop()+$window.height(); var windowScrollTop = $window.scrollTop() if( windowScrollTop > topOfElement && windowScrollTop < bottomOfElement) { // Element is partially visible (above viewable area) console.log("Element is partially visible (above viewable area)"); }else if( windowScrollTop > bottomOfElement && windowScrollTop > topOfElement ) { // Element is hidden (above viewable area) console.log("Element is hidden (above viewable area)"); }else if( scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement ) { // Element is hidden (below viewable area) console.log("Element is hidden (below viewable area)"); }else if( scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement ) { // Element is partially visible (below viewable area) console.log("Element is partially visible (below viewable area)"); }else{ // Element is completely visible console.log("Element is completely visible"); } });


Mi versión más corta y más rápida.

function isElementOutViewport(el){ var rect = el.getBoundingClientRect(); return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight; }

agregue jsFiddle según sea necesario https://jsfiddle.net/on1g619L/1/


Todas las respuestas que he encontrado aquí solo verifican si el elemento está ubicado dentro de la ventana gráfica actual . Pero eso no quiere decir que sea visible .
¿Qué sucede si el elemento dado está dentro de un div con contenido desbordado y se desplaza fuera de la vista?

Para resolver eso, tendrías que verificar si el elemento está contenido por todos los padres.
Mi solución hace exactamente eso:

También le permite especificar qué parte del elemento debe estar visible.

Element.prototype.isVisible = function(percentX, percentY){ var tolerance = 0.01; //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals if(percentX == null){ percentX = 100; } if(percentY == null){ percentY = 100; } var elementRect = this.getBoundingClientRect(); var parentRects = []; var element = this; while(element.parentElement != null){ parentRects.push(element.parentElement.getBoundingClientRect()); element = element.parentElement; } var visibleInAllParents = parentRects.every(function(parentRect){ var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left); var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top); var visiblePercentageX = visiblePixelX / elementRect.width * 100; var visiblePercentageY = visiblePixelY / elementRect.height * 100; return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY; }); return visibleInAllParents; };

Esta solución ignoró el hecho de que los elementos pueden no ser visibles debido a otros hechos, como la opacity: 0 .

He probado esta solución en Chrome e Internet Explorer 11.


Tuve la misma pregunta y la resolví utilizando getBoundingClientRect (). Este código es completamente ''genérico'' y solo debe escribirse una vez para que funcione (no es necesario que lo escriba para cada elemento que desee saber que se encuentra en la ventana). Este código solo verifica si está verticalmente en la ventana gráfica no horizontalmente . En este caso, la variable (matriz) ''elementos'' contiene todos los elementos que está verificando que estén verticalmente en la ventana gráfica, así que tome cualquier elemento que desee en cualquier lugar y almacénelos allí. El ''for loop'', recorre cada elemento y comprueba si está verticalmente en la ventana gráfica. Este código se ejecuta cada vez que el usuario se desplaza! Si la parte superior de getBoudingClientRect (). Es inferior a 3/4 de la ventana gráfica (el elemento es un cuarto en la ventana gráfica), se registra como ''en la ventana gráfica''. Dado que el código es genérico, querrá saber qué elemento está en la ventana gráfica. Para averiguarlo, puede determinarlo por atributo personalizado, nombre de nodo, id, nombre de clase y más. Aquí está mi código (Dime si no funciona, se ha probado en IE 11, FireFox 40.0.3, Chrome versión 45.0.2454.85 m, Opera 31.0.1889.174 y Edge con Windows 10, [aún no Safari] ) ...

//scrolling handlers... window.onscroll = function(){ var elements = document.getElementById(''whatever'').getElementsByClassName(''whatever''); for(var i = 0; i != elements.length; i++) { if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 && elements[i].getBoundingClientRect().top > 0) { console.log(elements[i].nodeName + '' '' + elements[i].className + '' '' + elements[i].id + '' is in the viewport; proceed with whatever code you want to do here.''); } };

Espero que esto ayude a alguien :-)


Una mejor solución:

function getViewportSize(w) { var w = w || window; if(w.innerWidth != null) return {w:w.innerWidth, h:w.innerHeight}; var d = w.document; if (document.compatMode == "CSS1Compat") { return { w: d.documentElement.clientWidth, h: d.documentElement.clientHeight }; } return { w: d.body.clientWidth, h: d.body.clientWidth }; } function isViewportVisible(e) { var box = e.getBoundingClientRect(); var height = box.height || (box.bottom - box.top); var width = box.width || (box.right - box.left); var viewport = getViewportSize(); if(!height || !width) return false; if(box.top > viewport.h || box.bottom < 0) return false; if(box.right < 0 || box.left > viewport.w) return false; return true; }


Ver la fuente de verge , que utiliza getBoundingClientRect . Es como:

function inViewport (el) { var r, html; if ( !el || 1 !== el.nodeType ) { return false; } html = document.documentElement; r = el.getBoundingClientRect(); return ( !!r && r.bottom >= 0 && r.right >= 0 && r.top <= html.clientHeight && r.left <= html.clientWidth ); }

Devuelve true si alguna parte del elemento está en la ventana gráfica.


Actualización: El tiempo avanza y así lo tienen nuestros navegadores. Esta técnica ya no se recomienda y debe usar la solución de @ Dan a continuación ( https://.com/a/7557433/5628 ) si no necesita ser compatible con IE <7.

Solución original (ahora desactualizada):

Esto comprobará si el elemento es completamente visible en la ventana gráfica actual:

function elementInViewport(el) { var top = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; var height = el.offsetHeight; while(el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return ( top >= window.pageYOffset && left >= window.pageXOffset && (top + height) <= (window.pageYOffset + window.innerHeight) && (left + width) <= (window.pageXOffset + window.innerWidth) ); }

Puede modificar esto simplemente para determinar si alguna parte del elemento es visible en la ventana gráfica:

function elementInViewport2(el) { var top = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; var height = el.offsetHeight; while(el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return ( top < (window.pageYOffset + window.innerHeight) && left < (window.pageXOffset + window.innerWidth) && (top + height) > window.pageYOffset && (left + width) > window.pageXOffset ); }


Utilizo esta función (solo comprueba si la y es inscreen ya que la mayoría de las veces no es necesaria la x)

function elementInViewport(el) { var elinfo = { "top":el.offsetTop, "height":el.offsetHeight, }; if (elinfo.top + elinfo.height < window.pageYOffset || elinfo.top > window.pageYOffset + window.innerHeight) { return false; } else { return true; } }


Para un desafío similar, disfruté mucho esta idea que expone un polyfill para scrollIntoViewIfNeeded() .

Todo el Kung Fu necesario para responder está dentro de este bloque:

var parent = this.parentNode, parentComputedStyle = window.getComputedStyle(parent, null), parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue(''border-top-width'')), parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue(''border-left-width'')), overTop = this.offsetTop - parent.offsetTop < parent.scrollTop, overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight), overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft, overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth), alignWithTop = overTop && !overBottom;

thisse refiere al elemento que desea saber si es ie overTopo overBottom- solo debe obtener la deriva ...