wake-up-neo.com

So prüfen Sie, ob das Element nach dem Scrollen sichtbar ist

Ich lade Elemente über AJAX. Einige davon sind nur sichtbar, wenn Sie auf der Seite nach unten scrollen.
Gibt es eine Möglichkeit, zu wissen, ob sich ein Element jetzt im sichtbaren Teil der Seite befindet?

1021
yoavf

Das sollte den Trick tun:

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 Utility-Funktion Mit dieser Funktion können Sie eine Utility-Funktion aufrufen, die das gewünschte Element akzeptiert und ob das Element vollständig oder teilweise angezeigt werden soll.

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

Verwendungszweck

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

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

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

Die beste Methode, die ich bisher gefunden habe, ist das jQuery-Plugin . Klappt wunderbar.

Imitiert ein benutzerdefiniertes Ereignis "Erscheinung", das ausgelöst wird, wenn ein Element in die Ansicht verschoben wird oder anderweitig für den Benutzer sichtbar wird.

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

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

116
Joe Lencioni

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

Demo hier (bitte auch die Fenstergröße ä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
};

EDIT 2016-03-26: Ich habe die Lösung aktualisiert, um das Scrollen an dem Element zu berücksichtigen, so dass es über dem oberen Bereich des scrollbaren Containers verborgen ist.EDIT 2018-10-08: Aktualisiert, wenn der Bildlauf außerhalb des Bildschirms erfolgt.

74
Ally

das jQuery Waypoints Plugin ist hier sehr schön.

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

Es gibt einige Beispiele auf der Seite des Plugins .

41
Fedir RYKHTIK

Wie wäre es mit

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

Danach können Sie auslösen, was Sie möchten, sobald das Element so angezeigt wird 

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

Das funktioniert gut für mich 

19
webicy

WebResourcesDepot hat ein Skript geschrieben, das beim Scrollen geladen werden soll, das jQuery vor einiger Zeit verwendet. Sie können ihre Live-Demo hier anzeigen. Das Rindfleisch ihrer Funktionalität war folgendes:

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

Verwendung der ("neuen") IntersectionObserver API

es ist sehr einfach und effizient festzustellen, ob ein Element im Ansichtsfenster sichtbar ist. Durch die Verwendung eines observer ist es nicht mehr erforderlich, ein scroll-Ereignis anzuhängen und den Ereignisrückruf manuell zu prüfen.

// this is the target which is observed
var target = document.querySelector('div');

// configure the intersection observer instance
var intersectionObserverOptions = {
  root: null,
  rootMargin: '150px',
  threshold: 1.0
}
    
var observer = new IntersectionObserver(onIntersection, intersectionObserverOptions);

// provice the observer with a target
observer.observe(target);

function onIntersection(entries){
  entries.forEach(entry => {
    console.clear();
    console.log(entry.intersectionRatio)
    target.classList.toggle('visible', entry.intersectionRatio > 0);
    
    // Are we in viewport?
    if (entry.intersectionRatio > 0) {
      // Stop watching 
      // observer.unobserve(entry.target);
    }
  });
}
.box{ width:100px; height:100px; background:red; margin:1000px; }
.box.visible{ background:green; }
Scroll both Vertically & Horizontally...
<div class='box'></div>


Browser-Supporttabelle anzeigen (nicht in IE/Safari unterstützt)

12
vsync

Tweeked Scott Dowdings coole Funktion für meine Anforderung- Diese Funktion wird verwendet, um herauszufinden, ob das Element gerade in den Bildschirm gescrollt wurde, d.

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

isScrolledIntoView ist eine sehr benötigte Funktion, also habe ich es versucht, es funktioniert für Elemente, die nicht höher als der Viewport sind, aber wenn das Element größer ist als der Viewport, funktioniert es nicht. Um dies zu beheben, ändern Sie einfach die Bedingung 

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

zu diesem:

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

Demo hier: http://jsfiddle.net/RRSmQ/

7
Robert

Es gibt ein plugin für jQuery mit dem Namen inview , das ein neues "inview" -Ereignis hinzufügt.


Hier ist etwas Code für ein jQuery-Plugin, das keine Ereignisse verwendet:

$.extend($.expr[':'],{
    inView: function(a) {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
            ot = $(a).offset().top,
            wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
        return ot > st && ($(a).height() + ot) < (st + wh);
    }
});

(function( $ ) {
    $.fn.inView = function() {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
        ot = $(this).offset().top,
        wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();

        return ot > st && ($(this).height() + ot) < (st + wh);
    };
})( jQuery );

Ich habe dies in einem Kommentar ( http://remysharp.com/2009/01/26/element-in-view-event-plugin/ ) von einem Kerl namens James gefunden

6
ness-EE

Dies berücksichtigt alle Füllungen, Ränder oder Ränder des Elements sowie Elemente, die größer als das Ansichtsfenster selbst sind.

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

Um es zu nennen, benutze so etwas:

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

console.log(canUserSeeIt); // true, if element is visible; false otherwise
6
Brent Barbata
function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop(),
        docViewBottom = docViewTop + $(window).height(),
        elemTop = $(elem).offset().top,
     elemBottom = elemTop + $(elem).height();
   //Is more than half of the element visible
   return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}
6
Pascal Gagneur

Bei den meisten Antworten wird nicht berücksichtigt, dass ein Element auch ausgeblendet werden kann, da es aus einem div-Bereich gerollt wird, nicht nur für die gesamte Seite.

Um diese Möglichkeit abzudecken, müssen Sie grundsätzlich prüfen, ob sich das Element innerhalb der Grenzen der einzelnen übergeordneten Elemente befindet.

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

Außerdem können Sie angeben, um wie viel Prozent es in jede Richtung sichtbar sein muss.
Es deckt nicht die Möglichkeit ab, dass es aufgrund anderer Faktoren wie display: hidden ausgeblendet wird.

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

6
Domysee

Hier ist eine andere Lösung aus http://web-profile.com.ua/

<script type="text/javascript">
$.fn.is_on_screen = function(){
    var win = $(window);
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right ||    viewport.bottom < bounds.top || viewport.top > bounds.bottom));
 };

if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info       
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
$(window).scroll(function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
});
</script>

Siehe in JSFiddle

5
Adrian P.

Einfache Vanille, um zu prüfen, ob das Element (el) im 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);
isVisible =  isScrolledIntoView(el, holder);
4
Denis Matafonov

Ich musste die Sichtbarkeit in Elementen innerhalb eines scrollbaren DIV-Containers überprüfen

    //p = DIV container scrollable
    //e = element
    function visible_in_container(p, e) {
        var z = p.getBoundingClientRect();
        var r = e.getBoundingClientRect();

        // Check style visiblilty and off-limits
        return e.style.opacity > 0 && e.style.display !== 'none' &&
               e.style.visibility !== 'hidden' &&
               !(r.top > z.bottom || r.bottom < z.top ||
                 r.left > z.right || r.right < z.left);
    }
3
Pigmalión

Aufbauend auf dieser großartigen Antwort können Sie es mit ES2015 + noch etwas vereinfachen:

function isScrolledIntoView(el) {
  const { top, bottom } = el.getBoundingClientRect()
  return top >= 0 && bottom <= window.innerHeight
}

Wenn Sie sich nicht dafür interessieren, dass der obere Teil des Fensters ausgeht und Sie nur darauf achten, dass der untere Teil angezeigt wurde, kann dies vereinfacht werden

function isSeen(el) {
  return el.getBoundingClientRect().bottom <= window.innerHeight
}

oder sogar der Einliner

const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight
3
rpearce

Die akzeptierte Antwort wurde geändert, sodass die Anzeigeeigenschaft des Elements auf etwas anderes als "none" gesetzt werden muss, um die sichtbare Qualität zu erreichen.

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

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();
  var elemDisplayNotNone = $(elem).css("display") !== "none";

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

Wenn Sie dies für das Scrollen eines Elements in einem anderen div ändern möchten,

function isScrolledIntoView (elem, divID) 

{

    var docViewTop = $('#' + divID).scrollTop();


    var docViewBottom = docViewTop + $('#' + divID).height();

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

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

Ein Beispiel basiert auf dieser Antwort , um zu prüfen, ob ein Element zu 75% sichtbar ist (d. H. Weniger als 25% davon sind außerhalb des Bildschirms).

function isScrolledIntoView(el) {
  // check for 75% visible
  var percentVisible = 0.75;
  var elemTop = el.getBoundingClientRect().top;
  var elemBottom = el.getBoundingClientRect().bottom;
  var elemHeight = el.getBoundingClientRect().height;
  var overhang = elemHeight * (1 - percentVisible);

  var isVisible = (elemTop >= -overhang) && (elemBottom <= window.innerHeight + overhang);
  return isVisible;
}
3
Brendan Nee

Sie können das Jquery-Plugin "onScreen" verwenden, um zu prüfen, ob sich das Element im aktuellen Ansichtsbereich befindet, wenn Sie einen Bildlauf ausführen. Das Plugin setzt ": onScreen" des Selektors auf "true", wenn der Selektor auf dem Bildschirm angezeigt wird ..__ Dies ist der Link für das Plugin, den Sie in Ihr Projekt einfügen können. " http://benpickles.github.io/onScreen/jquery.onscreen.min.js "

Sie können das folgende Beispiel ausprobieren, das für mich funktioniert.

$(document).scroll(function() {
    if($("#div2").is(':onScreen')) {
        console.log("Element appeared on Screen");
        //do all your stuffs here when element is visible.
    }
    else {
        console.log("Element not on Screen");
        //do all your stuffs here when element is not visible.
    }
});

HTML Quelltext:

<div id="div1" style="width: 400px; height: 1000px; padding-top: 20px; position: relative; top: 45px"></div> <br>
<hr /> <br>
<div id="div2" style="width: 400px; height: 200px"></div>

CSS:

#div1 {
    background-color: red;
}
#div2 {
    background-color: green;
}
3
Vasuki Dileep

Ich habe eine solche Methode in meiner Anwendung, aber es wird kein jQuery verwendet:

/* Get the TOP position of a given element. */
function getPositionTop(element){
    var offset = 0;
    while(element) {
        offset += element["offsetTop"];
        element = element.offsetParent;
    }
    return offset;
}

/* Is a given element is visible or not? */
function isElementVisible(eltId) {
    var elt = document.getElementById(eltId);
    if (!elt) {
        // Element not found.
        return false;
    }
    // Get the top and bottom position of the given element.
    var posTop = getPositionTop(elt);
    var posBottom = posTop + elt.offsetHeight;
    // Get the top and bottom position of the *visible* part of the window.
    var visibleTop = document.body.scrollTop;
    var visibleBottom = visibleTop + document.documentElement.offsetHeight;
    return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}

Edit: Diese Methode funktioniert gut für I.E. (mindestens Version 6). Lesen Sie die Kommentare zur Kompatibilität mit FF.

3
Romain Linsolas

Hier ist ein Weg, um mit Mootools dasselbe zu erreichen, sowohl horizontal als auch vertikal.

Element.implement({
inVerticalView: function (full) {
    if (typeOf(full) === "null") {
        full = true;
    }

    if (this.getStyle('display') === 'none') {
        return false;
    }

    // Window Size and Scroll
    var windowScroll = window.getScroll();
    var windowSize = window.getSize();
    // Element Size and Scroll
    var elementPosition = this.getPosition();
    var elementSize = this.getSize();

    // Calculation Variables
    var docViewTop = windowScroll.y;
    var docViewBottom = docViewTop + windowSize.y;
    var elemTop = elementPosition.y;
    var elemBottom = elemTop + elementSize.y;

    if (full) {
        return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
            && (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
    } else {
        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }
},
inHorizontalView: function(full) {
    if (typeOf(full) === "null") {
        full = true;
    }

    if (this.getStyle('display') === 'none') {
        return false;
    }

    // Window Size and Scroll
    var windowScroll = window.getScroll();
    var windowSize = window.getSize();
    // Element Size and Scroll
    var elementPosition = this.getPosition();
    var elementSize = this.getSize();

    // Calculation Variables
    var docViewLeft = windowScroll.x;
    var docViewRight = docViewLeft + windowSize.x;
    var elemLeft = elementPosition.x;
    var elemRight = elemLeft + elementSize.x;

    if (full) {
        return ((elemRight >= docViewLeft) && (elemLeft <= docViewRight)
            && (elemRight <= docViewRight) && (elemLeft >= docViewLeft) );
    } else {
        return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft));
    }
},
inView: function(full) {
    return this.inHorizontalView(full) && this.inVerticalView(full);
}});
3
bmlkc

Diese Methode gibt true zurück, wenn ein Teil des Elements auf der Seite sichtbar ist. Es hat in meinem Fall besser funktioniert und kann jemand anderem helfen.

function isOnScreen(element) {
  var elementOffsetTop = element.offset().top;
  var elementHeight = element.height();

  var screenScrollTop = $(window).scrollTop();
  var screenHeight = $(window).height();

  var scrollIsAboveElement = elementOffsetTop + elementHeight - screenScrollTop >= 0;
  var elementIsVisibleOnScreen = screenScrollTop + screenHeight - elementOffsetTop >= 0;

  return scrollIsAboveElement && elementIsVisibleOnScreen;
}
2
Rafael Garcia

Einfache Änderung für scrollbare div (Container)

var isScrolledIntoView = function(elem, container) {
    var containerHeight = $(container).height();
    var elemTop = $(elem).position().top;
    var elemBottom = elemTop + $(elem).height();
    return (elemBottom > 0 && elemTop < containerHeight);
}

HINWEIS: Dies funktioniert nicht, wenn das Element größer als das scrollbare div ist.

2

Ich bevorzuge die Verwendung von jQuery expr

jQuery.extend(jQuery.expr[':'], {  
    inview: function (elem) {
        var t = $(elem);
        var offset = t.offset();
        var win = $(window); 
        var winST = win.scrollTop();
        var elHeight = t.outerHeight(true);

        if ( offset.top > winST - elHeight && offset.top < winST + elHeight + win.height()) {
            return true;    
        }    
        return false;  
    }
});

so können Sie es auf diese Weise verwenden

$(".my-elem:inview"); //returns only element that is in view
$(".my-elem").is(":inview"); //check if element is in view
$(".my-elem:inview").length; //check how many elements are in view

Sie können diesen Code einfach in der scroll-Ereignisfunktion usw. hinzufügen, um ihn jedes Mal zu überprüfen, wenn der Benutzer die Ansicht durchläuft.

2
pie6k

Ich war auf der Suche nach einem Weg, um zu sehen, ob das Element bald in Sicht kommt. Durch Erweiterung der obigen Schnipsel gelang es mir, dies zu tun. Ich dachte, ich würde das hier nur für den Fall lassen, dass es jemandem helfen wird

Elm = ist das Element, das Sie überprüfen möchten, in der Ansicht

scrollElement = Sie können window oder ein übergeordnetes Element übergeben, das einen Bildlauf aufweist

offset = wenn es ausgelöst werden soll, wenn das Element 200px entfernt ist, bevor es auf dem Bildschirm angezeigt wird, übergeben Sie 200 

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

2
Sonny Lloyd

Ich habe diese kurze jQuery-Funktionserweiterung angepasst, die Sie gerne verwenden können (MIT-Lizenz).

/**
 * returns true if an element is visible, with decent performance
 * @param [scope] scope of the render-window instance; default: window
 * @returns {boolean}
 */
jQuery.fn.isOnScreen = function(scope){
    var element = this;
    if(!element){
        return;
    }
    var target = $(element);
    if(target.is(':visible') == false){
        return false;
    }
    scope = $(scope || window);
    var top = scope.scrollTop();
    var bot = top + scope.height();
    var elTop = target.offset().top;
    var elBot = elTop + target.height();

    return ((elBot <= bot) && (elTop >= top));
};
2
Lorenz Lo Sauer

Ich habe eine Komponente für die Aufgabe geschrieben, die für die Verarbeitung einer großen Anzahl von Elementen extrem schnell (mit einem Wert von <10ms für 1000 Elemente auf einem langsamen mobilen Gerät) gedacht ist. 

Es funktioniert mit jedem Bildlaufcontainer-Typ, auf den Sie zugreifen können - Fenster, HTML-Elemente, eingebetteter Iframe, erzeugtes untergeordnetes Fenster - und ist sehr flexibel bei der Erkennung ( vollständige oder teilweise Sichtbarkeit , Rahmen) oder Inhaltsfeld , benutzerdefiniertes Toleranzzone , usw. ).

Eine große, meist automatisch generierte Testsuite stellt sicher, dass sie wie angekündigt funktioniert, Cross-Browser .

Probieren Sie es aus, wenn Sie möchten: jQuery.isInView . Ansonsten finden Sie möglicherweise Anregungen im Quellcode, z. Hier .

1
hashchange

Eine effizientere Version von diese Antwort :

 /**
 * Is element within visible region of a scrollable container
 * @param {HTMLElement} el - element to test
 * @returns {boolean} true if within visible region, otherwise false
 */
 function isScrolledIntoView(el) {
      var rect = el.getBoundingClientRect();
      return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
 }
1
John Doherty

Es gibt über 30 Antworten auf diese Frage, und keine von ihnen verwendet die erstaunlich einfache, reine JS-Lösung, die ich verwendet habe. Um dieses Problem zu lösen, ist es nicht erforderlich, jQuery zu laden, da viele andere dies tun.

Um festzustellen, ob sich das Element innerhalb des Darstellungsbereichs befindet, müssen wir zuerst die Position des Elements im Körper bestimmen. Wir müssen das nicht rekursiv machen, wie ich es einmal dachte. Stattdessen können wir element.getBoundingClientRect() verwenden.

pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;

Dieser Wert ist die Y-Differenz zwischen der Oberkante des Objekts und der Oberkante des Körpers.

Wir müssen dann feststellen, ob das Element in Sicht ist. Bei den meisten Implementierungen wird gefragt, ob sich das gesamte Element innerhalb des Darstellungsbereichs befindet. Daher werden wir uns damit befassen.

Zuallererst ist die oberste Position des Fensters: window.scrollY.

Wir können die untere Position des Fensters ermitteln, indem Sie die Höhe des Fensters zu seiner oberen Position hinzufügen:

var window_bottom_position = window.scrollY + window.innerHeight;

Lassen Sie uns eine einfache Funktion erstellen, um die oberste Position des Elements zu erhalten:

function getElementWindowTop(elem){
    return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}

Diese Funktion gibt die oberste Position des Elements innerhalb des Fensters zurück oder 0, wenn Sie etwas anderes als ein Element mit der .getBoundingClientRect()-Methode übergeben. Diese Methode gibt es schon lange, daher sollten Sie sich keine Sorgen machen, dass Ihr Browser sie nicht unterstützt.

Nun ist die oberste Position unseres Elements:

var element_top_position = getElementWindowTop(element);

Und die unterste Position des Elements ist:

var element_bottom_position = element_top_position + element.clientHeight;

Jetzt können Sie feststellen, ob sich das Element im Ansichtsfenster befindet, indem Sie prüfen, ob sich die untere Position des Elements unter der oberen Position des Ansichtsfensters befindet, und indem Sie prüfen, ob die obere Position des Elements höher ist als die untere Position des Ansichtsfensters:

if(element_bottom_position >= window.scrollY 
&& element_top_position <= window_bottom_position){
    //element is in view
else
    //element is not in view

Von dort aus können Sie die Logik ausführen, um eine in-view-Klasse zu Ihrem Element hinzuzufügen oder zu entfernen, die Sie später mit Übergangseffekten in Ihrem CSS behandeln können.

Ich bin absolut erstaunt, dass ich diese Lösung nirgendwo anders gefunden habe, aber ich glaube, dass dies die sauberste und effektivste Lösung ist und es nicht erforderlich ist, dass Sie jQuery laden!

1
WebWanderer

Ich wollte nur mitteilen, dass ich dies mit meinem Skript kombiniert habe, um das div so zu verschieben, dass es immer im Blickfeld bleibt:

    $("#accordion").on('click', '.subLink', function(){
        var url = $(this).attr('src');
        updateFrame(url);
        scrollIntoView();
    });

    $(window).scroll(function(){
            changePos();
    });

  function scrollIntoView()
  {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();    
        var elemTop = $("#divPos").offset().top;
        var elemBottom = elemTop + $("#divPos").height();               
        if (elemTop < docViewTop){
            $("#divPos").offset({top:docViewTop});
        }
   }

   function changePos(){        
    var scrTop = $(window).scrollTop();
    var frmHeight = $("#divPos").height()
        if ((scrTop < 200) || (frmHeight > 800)){   
         $("#divPos").attr("style","position:absolute;");
        }else{
          $("#divPos").attr("style","position:fixed;top:5px;");
        }
    }
1
tree

Ein einfaches Plugin erstellt, das erkennt, ob ein Element in einem scrollbaren Container sichtbar ist

    $.fn.isVisible = function(){

      var win;
      if(!arguments[0])
      {
        console.error('Specify a target;');
        return false;
      }
      else
      {
        win = $(arguments[0]);
      }
      var viewport = {};
      var bounds = this.offset();
      bounds.right = bounds.left + this.outerWidth();
      bounds.bottom = bounds.top + this.outerHeight();
      viewport.bottom = win.height() + win.offset().top;
      return (!( bounds.top > viewport.bottom) && (win.offset().top < bounds.bottom));
    };

Nenne es so $('elem_to_check').isVisible('scrollable_container');

Ich hoffe es hilft.

0
user3491125

Wir können so etwas in modernen Browsern mit ES6 machen:

const isFullySeen = el => el &&
  typeof el.getBoundingClientRect === 'function' &&
  el.getBoundingClientRect()['bottom'] + window.scrollY <= 
    window.innerHeight + window.scrollY && 
  el.getBoundingClientRect()['top'] + window.scrollY <= 
    window.innerHeight + window.scrollY;
0
Alireza

Überprüft, ob das Element überhaupt auf dem Bildschirm angezeigt wird, und nicht der Ansatz der akzeptierten Antwort, der prüft, ob das div vollständig auf dem Bildschirm angezeigt wird (was nicht funktioniert, wenn div größer als der Bildschirm ist). In reinem Javascript:

/**
 * Checks if element is on the screen (Y axis only), returning true
 * even if the element is only partially on screen.
 *
 * @param element
 * @returns {boolean}
 */
function isOnScreenY(element) {
    var screen_top_position = window.scrollY;
    var screen_bottom_position = screen_top_position + window.innerHeight;

    var element_top_position = element.offsetTop;
    var element_bottom_position = element_top_position + element.offsetHeight;

    return (inRange(element_top_position, screen_top_position, screen_bottom_position)
    || inRange(element_bottom_position, screen_top_position, screen_bottom_position));
}

/**
 * Checks if x is in range (in-between) the
 * value of a and b (in that order). Also returns true
 * if equal to either value.
 *
 * @param x
 * @param a
 * @param b
 * @returns {boolean}
 */
function inRange(x, a, b) {
    return (x >= a && x <= b);
}
0
willsquire

Das einzige Plugin, das für mich konsequent funktioniert, ist: https://github.com/customd/jquery-visible

Ich habe dieses Plugin nach GWT portiert, da ich Jquery nicht als Abhängigkeit hinzufügen wollte, nur um das Plugin zu verwenden. Hier ist mein (einfacher) Port (einschließlich der Funktionen, die ich für meinen Anwendungsfall benötige):

public static boolean isVisible(Element e)
{
    //vp = viewPort, b = bottom, l = left, t = top, r = right
    int vpWidth   = Window.getClientWidth();
    int vpHeight = Window.getClientHeight();


    boolean tViz = ( e.getAbsoluteTop() >= 0 && e.getAbsoluteTop()<  vpHeight);
    boolean bViz = (e.getAbsoluteBottom() >  0 && e.getAbsoluteBottom() <= vpHeight);
    boolean lViz = (e.getAbsoluteLeft() >= 0 && e.getAbsoluteLeft() < vpWidth);
    boolean rViz = (e.getAbsoluteRight()  >  0 && e.getAbsoluteRight()  <= vpWidth);

    boolean vVisible   = tViz && bViz;
    boolean hVisible   = lViz && rViz;

    return hVisible && vVisible;
}
0
Click Upvote