Pregunta Verifique si el elemento está visible después de desplazarse


Estoy cargando elementos a través de AJAX. Algunos de ellos solo son visibles si se desplaza hacia abajo en la página.
¿Hay alguna manera de saber si un elemento se encuentra ahora en la parte visible de la página?


976
2018-01-28 10:00


origen


Respuestas:


Esto debería funcionar:

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Función de utilidad simple Esto le permitirá llamar a una función de utilidad que acepte el elemento que está buscando y si desea que el elemento esté totalmente a la vista o parcialmente.

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

Uso

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
    console.log('in view');
} else {
    console.log('out of view');
}

1133
2018-01-28 15:36



Esta respuesta en Vanilla:

function isScrolledIntoView(el) {
    var rect = el.getBoundingClientRect();
    var elemTop = rect.top;
    var elemBottom = rect.bottom;

    // Only completely visible elements return true:
    var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
    // Partially visible elements return true:
    //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
    return isVisible;
}

296
2018-03-18 13:31



El mejor método que he encontrado hasta ahora es el jQuery aparece el complemento. Funciona de maravilla.

Imita un evento "aparecer" personalizado, que se activa cuando un elemento se desplaza a la vista o se vuelve visible para el usuario.

$('#foo').appear(function() {
  $(this).text('Hello world');
});

Este complemento se puede utilizar para evitar solicitudes innecesarias de contenido que está oculto o fuera del área visible.


113
2017-08-20 21:31



Aquí está mi solución de JavaScript puro que funciona si está escondida dentro de un contenedor desplazable también.

Demo aquí (intente cambiar el tamaño de la ventana también)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode;
  do {
    rect = el.getBoundingClientRect();
    if (top <= rect.bottom === false) return false;
    // Check if the element is out of view due to a container scrolling
    if ((top + height) <= rect.top) return false
    el = el.parentNode;
  } while (el != document.body);
  // Check its within the document viewport
  return top <= document.documentElement.clientHeight;
};

EDITAR 2016-03-26: actualicé la solución para dar cuenta de que se desplazó más allá del elemento, por lo que está oculta encima de la parte superior del contenedor desplazable.


65
2018-02-07 12:02



El complemento jQuery Waypoints va muy bien aquí.

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

Hay algunos ejemplos en sitio del complemento.


40
2017-12-04 12:08



WebResourcesDepot escribió un script para cargar mientras se desplaza que usa jQuery hace tiempo. Puedes ver su Demostración en vivo aquí. La carne de su funcionalidad era esta:

$(window).scroll(function(){
  if  ($(window).scrollTop() == $(document).height() - $(window).height()){
    lastAddedLiveFunc();
  }
});

function lastAddedLiveFunc() { 
  $('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
  $.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
    function(data){
        if (data != "") {
          $(".wrdLatest:last").after(data);         
        }
      $('div#lastPostsLoader').empty();
    });
};

14
2018-01-28 14:14



Qué tal si

function isInView(elem){
   return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}

Después de eso, puedes activar lo que quieras una vez que el elemento esté a la vista como este

$(window).scroll(function(){
   if (isInView($('.classOfDivToCheck')))
      //fire whatever you what 
      dothis();
})

Eso funciona bien para mí


14
2018-04-29 10:24



Tweeked la función genial de Scott Dowding para mi requisito- esto se usa para encontrar si el elemento acaba de desplazarse en la pantalla, es decir, su borde superior.

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}

12
2018-04-30 16:08



isScrolledIntoView es una función muy necesaria, así que lo intenté, funciona para elementos que no sean más altos que la ventana gráfica, pero si el elemento es más grande que la ventana gráfica, no funciona. Para solucionar esto, cambia fácilmente la condición

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

a esto:

return (docViewBottom >= elemTop && docViewTop <= elemBottom);

Vea la demostración aquí: http://jsfiddle.net/RRSmQ/


6
2017-10-23 17:30



Esto considera cualquier relleno, borde o margen que tenga el elemento, así como también elementos más grandes que la propia ventana gráfica.

function inViewport($ele) {
    var lBound = $(window).scrollTop(),
        uBound = lBound + $(window).height(),
        top = $ele.offset().top,
        bottom = top + $ele.outerHeight(true);

    return (top > lBound && top < uBound)
        || (bottom > lBound && bottom < uBound)
        || (lBound >= top && lBound <= bottom)
        || (uBound >= top && uBound <= bottom);
}

Para llamarlo, usa algo como esto:

var $myElement = $('#my-element'),
    canUserSeeIt = inViewport($myElement);

console.log(canUserSeeIt); // true, if element is visible; false otherwise

6
2017-12-30 01:54



La mayoría de las respuestas aquí no tienen en cuenta que un elemento también se puede ocultar porque se desplaza fuera de la vista de un div, no solo de toda la página.

Para cubrir esa posibilidad, básicamente debes verificar si el elemento está ubicado dentro de los límites de cada uno de sus padres.

Esta solución hace exactamente eso:

function(element, 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 = element.getBoundingClientRect();
    var parentRects = [];

    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;
};

También le permite especificar a qué porcentaje debe estar visible en cada dirección.
No cubre la posibilidad de que pueda estar oculto debido a otros factores, como display: hidden.

Esto debería funcionar en todos los navegadores principales, ya que solo usa getBoundingClientRect. Personalmente lo probé en Chrome e Internet Explorer 11.


6
2018-06-26 13:35