Website-Suche

javascript - Wie überprüft man, ob ein Element nach dem Scrollen sichtbar ist?


Ich lade Elemente über AJAX. Einige von ihnen sind nur sichtbar, wenn man auf der Seite nach unten scrollt. Gibt es eine Möglichkeit, herauszufinden, ob ein Element jetzt im sichtbaren Teil der Seite ist?

Antwort #1

Das sollte funktionieren:

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

Einfache Hilfsfunktion Dies ermöglicht es Ihnen, eine Hilfsfunktion aufzurufen, die das Element akzeptiert, nach dem Sie suchen, und ob Sie möchten, dass das Element vollständig sichtbar oder teilweise sichtbar ist.

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();

Verwendung

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

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

Antwort #2

Diese Antwort in 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;
}

Antwort #3

Verwendung der IntersectionObserver-API

(nativen in modernen Browsern)


Es ist einfach und effizient festzustellen, ob ein Element im Ansichtsfenster oder in einem beliebigen scrollbaren Container sichtbar ist, indem man einen Observer verwendet.

Die Notwendigkeit, ein scroll-Ereignis anzuhängen und das Ereignis im Callback manuell zu überprüfen, entfällt, was effizienter ist:

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: .5 // percentage of target's visible area. Triggers "onIntersection"
})

// callback is called on intersection change
function onIntersection(entries, opts){
  entries.forEach(entry =>  
    entry.target.classList.toggle('visible', entry.isIntersecting)
  )
}

// Use the observer to observe an element
observer.observe( document.querySelector('.box') )

// To stop observing:
// observer.unobserve(entry.target)
span{ position:fixed; top:0; left:0; }
.box{ width:100px; height:100px; background:red; margin:1000px; transition:.75s; }
.box.visible{ background:green; border-radius:50%; }
<span>Scroll both Vertically &amp; Horizontally...</span>
<div class='box'></div>

Unterstützt von modernen Browsern, einschließlich mobiler Browser. In IE nicht unterstützt - Browser-Support-Tabelle anzeigen

Antwort #4

Aktualisierung: IntersectionObserver verwenden

Die beste Methode, die ich bisher gefunden habe, ist das jQuery Appear-Plugin. Funktioniert wie ein Zauber.

Ahmt ein benutzerdefiniertes „appear“-Ereignis nach, das ausgelöst wird, wenn ein Element in den sichtbaren Bereich scrollt oder auf andere Weise für den Benutzer sichtbar wird.

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

Dieses Plugin kann verwendet werden, um unnötige Anfragen für Inhalte zu verhindern, die verborgen sind oder sich außerhalb des sichtbaren Bereichs befinden.

Antwort #5

Hier ist meine reine JavaScript-Lösung, die funktioniert, wenn sie auch in einem scrollbaren Container verborgen ist.

Demo hier (versuche auch, das Fenster zu ändern)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode
  // Check if bottom of the element is off the page
  if (rect.bottom < 0) return false
  // Check its within the document viewport
  if (top > document.documentElement.clientHeight) return false
  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)
  return true
};

BEARBEITUNG 26.03.2016: Ich habe die Lösung aktualisiert, um das Scrollen am Element vorbei zu berücksichtigen, sodass es oberhalb des scrollbaren Containers verborgen ist. BEARBEITUNG 08.10.2018: Aktualisiert, um zu behandeln, wenn es aus dem Blickfeld über dem Bildschirm gescrollt wird.

Antwort #6

Einfache Version, um zu überprüfen, ob ein Element (el) in einem scrollbaren Div (holder) sichtbar ist

function isElementVisible (el, holder) {
  holder = holder || document.body
  const { top, bottom, height } = el.getBoundingClientRect()
  const holderRect = holder.getBoundingClientRect()

  return top <= holderRect.top
    ? holderRect.top - top <= height
    : bottom - holderRect.bottom <= height
}

Verwendung mit jQuery:

var el = $('tr:last').get(0);
var holder = $('table').get(0);
var isVisible = isElementVisible(el, holder);

Antwort #7

Das jQuery Waypoints-Plugin passt hier sehr gut.

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

Auf der Website des Plugins gibt es einige Beispiele.

Antwort #8

Wie wäre es mit

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

Danach können Sie alles auslösen, was Sie möchten, sobald das Element wie folgt sichtbar ist

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

Das passt mir ganz gut

Antwort #9

Ich habe Scott Dowdings coole Funktion für meine Anforderungen angepasst - sie wird verwendet, um herauszufinden, ob das Element gerade in den Bildschirm gescrollt wurde, d.h. seine obere Kante.

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

Antwort #10

WebResourcesDepot schrieb vor einiger Zeit ein Skript zum Laden beim Scrollen, das jQuery verwendet. Sie können deren Live-Demo hier ansehen. Der Kern ihrer Funktionalität war dies:

$(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();
    });
};

Antwort #11

Die meisten Antworten hier berücksichtigen nicht, dass ein Element auch deshalb verborgen sein kann, weil es aus dem Sichtbereich eines Divs gescrollt wurde, nicht nur aus der gesamten Seite.

Um diese Möglichkeit abzudecken, muss man im Grunde prüfen, ob das Element innerhalb der Grenzen jedes seiner Eltern positioniert ist.

Diese Lösung macht genau das:

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

Es erlaubt Ihnen auch anzugeben, zu welchem Prozentsatz es in jede Richtung sichtbar sein muss.
Es deckt nicht die Möglichkeit ab, dass es aufgrund anderer Faktoren verborgen sein kann, wie z.B. display: hidden.

Dies sollte in allen gängigen Browsern funktionieren, da es nur getBoundingClientRect verwendet. Ich habe es persönlich in Chrome und Internet Explorer 11 getestet.

Antwort #12

Die einfachste Lösung, die ich dafür gefunden habe, ist Intersection Observer API:

var observer = new IntersectionObserver(function(entries) {
    if(entries[0].isIntersecting === true)
        console.log('Element has just become visible in screen');
}, { threshold: [0] });

observer.observe(document.querySelector("#main-container"));

Verwandte Artikel