web-dev-qa-db-fra.com

Comment obtenir des objets d'éléments visibles à l'écran dans jQuery?

J'ai une liste d'objets dans DOM, qui est plus longue que la zone de hauteur d'écran.

Je dois détecter les objets visibles à l'écran uniquement pour créer quelque chose comme une arborescence de la chronologie. ( quelque chose comme sur l'image ci-dessous ):

enter image description here

Mon DOM ressemble à ceci:

<!-- elements visibility on screen to be DETECTED -->
<div id="elements">
    <div id="elem-1">Lorem ipsum</div>
    <div id="elem-2">Lorem ipsum</div>
    <div id="elem-3">Lorem ipsum</div>
    <div id="elem-4">Lorem ipsum</div>
    <div id="elem-5">Lorem ipsum</div>
    <div id="elem-6">Lorem ipsum</div>
    <div id="elem-7">Lorem ipsum</div>
    <div id="elem-8">Lorem ipsum</div>
</div>


<!--elements visibility on screen to be AFFECTED  -->
<ul id="timeline">
    <li view-id="elem-1">Elem-1</li>
    <li view-id="elem-2">Elem-2</li>
    <li view-id="elem-3" class="active">Elem-3</li>
    <li view-id="elem-4" class="active">Elem-4</li>
    <li view-id="elem-5" class="active">Elem-5</li>
    <li view-id="elem-6" class="active">Elem-6</li>
    <li view-id="elem-7">Elem-7</li>
    <li view-id="elem-8">Elem-8</li>
</ul>

Mon objectif est de détecter les identifiants des éléments visibles à l'écran à partir de #elements conteneur et attribuer la classe active aux éléments correspondants dans #timeline récipient.

J'ai besoin de faire ce processus sur l'événement Scroll.

Des idées pour y parvenir?

46
user2893747

Tout d'abord on-screen visible area est appelé Viewport.

image is took from OP and cleaned up in Photoshop

(l'image est extraite de OP. Effacée et modifiée dans Photoshop )


Il vous suffit donc de détecter tous les éléments de votre Viewport.

Cela peut être réalisé en utilisant de nombreux plugins pour jQuery, mais je vais vous expliquer un exemple, qui s'appelle jQuery withinviewport

Lien vers la source et la documentation sur: [withInViewport - Github]


Étape 1:

Téléchargez les plugins et incluez le framework jQuery et le plugin withinviewport dans votre script:

<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script src="withinViewport.js"></script>
<script src="jquery.withinviewport.js"></script>

.

Étape 2:

Fonction d'initialisation sur l'événement scroll:

$(window).bind("scroll", function() {
    //your code placeholder
});

.

Étape 3:

Utilisez le sélecteur withinviewport pour obtenir tous les éléments dans votre fenêtre d'affichage et, pour chaque élément, ajoutez la classe à l'élément de liste correspondant dans votre #timeline récipient:

$("#elements > div").withinviewport().each(function() {
   $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
});

Étape 4:

Mettez tous ensemble:

$(window).bind("scroll", function() {

    //clear all active class
    $('#timeline > li').removeClass('active');

    //add active class to timeline
    $("#elements > div").withinviewport().each(function() {
         $('#timeline > li[view-id="'+$(this)[0].id+'"]').addClass('active');
    });
});

.


.

De plus, ce plugin vous donne la possibilité de définir le décalage supérieur, inférieur, gauche et droit pour le port de vue.

Voir la démo ici : http://patik.com/code/within-viewport/

41
zur4ik