Un callback quand on scroll au niveau d’un élément

Cette technique est de plus en plus répandue. Sur certains sites, on peut se rendre compte que des contenus sont chargés dynamiquement en fonction de notre scroll : Google Actualités, jQuery.com, Clubic…

Pour ces deux derniers, les commentaires des articles sont chargés uniquement si on scroll « à leur niveau ».
Quand on y réfléchit c’est plutôt normal, pourquoi charger dès le départ des éléments qui ne seront même pas lus par l’internaute ? Ceci permet d’économiser des ressources serveur, notamment des appels SQL.

Je vous propose de voir comment ceci peut fonctionner, c’est plutôt simple et après on ne s’en passe plus !

Je vais reprendre le système de commentaires, lorsque notre scroll va arriver au niveau de #comments, on va uniquement changer son texte, on peut imaginer faire n’importe quoi.
Le plus important est de récupérer ce fameux callback.

<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ultrices dictum ante, nec interdum felis mollis vitae. Mauris porta urna nec lorem semper cursus. Etiam nec dignissim turpis. Integer a lobortis orci. Suspendisse rhoncus massa dapibus ligula tempor molestie. Etiam consectetur quam et felis interdum sit amet posuere quam fermentum. Suspendisse nibh nulla, auctor et auctor at, placerat sit amet erat.

Sed tempor mi id erat viverra vestibulum. Donec euismod justo metus. Integer eleifend lacus sit amet dui ullamcorper quis elementum tellus placerat. Quisque ac justo ligula. Ut molestie gravida risus ac vestibulum. Vivamus semper eros vitae dui fringilla eget bibendum odio interdum. Suspendisse non blandit augue. Fusce vitae velit metus, ac vestibulum dui. Fusce eget velit arcu. Aenean quis varius enim.

In viverra neque libero. Ut non pretium tortor. Duis nunc ipsum, aliquet varius dignissim nec, ullamcorper id arcu. Morbi nec cursus sem. Ut ac justo nulla, eu elementum diam. Suspendisse est elit, tincidunt eu mattis accumsan, placerat quis ipsum. Nunc tincidunt, arcu eu vulputate dapibus, lectus leo ullamcorper quam, id fermentum leo mi iaculis augue. Proin vitae odio pharetra nulla imperdiet aliquam. Aenean sed neque erat, non faucibus leo. Sed metus augue, imperdiet ut lobortis ac, pulvinar vel dolor. Curabitur dui quam, aliquam ac mattis quis, bibendum a mi. Sed viverra libero non risus dictum ac venenatis metus rutrum. Nulla consectetur mauris vitae nisl viverra adipiscing. Proin pellentesque erat a libero cursus sed laoreet velit aliquam. Mauris convallis semper quam, sit amet tempor nisl fermentum sit amet.

Donec fringilla pellentesque orci, ac pellentesque nunc dictum id. Fusce quis lectus mauris. Nunc mollis vulputate purus, vitae malesuada massa varius ac. Vivamus varius, massa sed dignissim laoreet, lorem magna luctus odio, eget sodales odio velit at felis. Nulla fringilla lacinia diam ac sagittis. Ut pharetra turpis id lectus porttitor at ultrices lorem accumsan. Etiam vitae congue nisl. Aenean non lectus nec lorem luctus pharetra. Proin malesuada, sem eget volutpat mollis, odio arcu fermentum ipsum, in vulputate sapien risus ut felis. Donec vulputate auctor mauris, in consequat eros accumsan sed. Fusce quis pharetra tortor. Aliquam ut dolor massa. Pellentesque id metus eu metus hendrerit elementum eu vel neque. Nullam tincidunt, libero sit amet interdum lobortis, risus ipsum ultricies urna, placerat iaculis eros lacus vitae mauris. Pellentesque nec lacus vel felis interdum egestas at a lacus.

Donec fringilla pellentesque orci, ac pellentesque nunc dictum id. Fusce quis lectus mauris. Nunc mollis vulputate purus, vitae malesuada massa varius ac. Vivamus varius, massa sed dignissim laoreet, lorem magna luctus odio, eget sodales odio velit at felis. Nulla fringilla lacinia diam ac sagittis. Ut pharetra turpis id lectus porttitor at ultrices lorem accumsan. Etiam vitae congue nisl. Aenean non lectus nec lorem luctus pharetra. Proin malesuada, sem eget volutpat mollis, odio arcu fermentum ipsum, in vulputate sapien risus ut felis. Donec vulputate auctor mauris, in consequat eros accumsan sed. Fusce quis pharetra tortor. Aliquam ut dolor massa. Pellentesque id metus eu metus hendrerit elementum eu vel neque. Nullam tincidunt, libero sit amet interdum lobortis, risus ipsum ultricies urna, placerat iaculis eros lacus vitae mauris. Pellentesque nec lacus vel felis interdum egestas at a lacus.

Etiam non arcu nec enim volutpat imperdiet. Mauris nec sem lacus. Etiam laoreet laoreet lacus non lacinia. Sed quis odio velit, id lobortis dolor. Nunc quam leo, tempor ac dapibus eget, commodo vel nulla. Sed aliquet, enim sit amet luctus egestas, nisi leo sollicitudin neque, non imperdiet urna ante in arcu. In ultrices sagittis orci egestas ultricies. Cras nisl mi, sodales vitae fringilla quis, vulputate convallis elit. Integer augue orci, vestibulum ut fermentum et, hendrerit ac diam. Nunc lectus sapien, molestie id posuere eget, sodales sit amet arcu. Mauris fringilla mi tincidunt urna porttitor porttitor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</div>

<div id="comments">Commentaires</div>
.content {
    width: 300px;   
}

Maintenant que la structure est en place, de quoi a-t-on besoin comme données pour créer notre callback ?

  • $(‘#comments’).offset().top : la position « top » de l’élément par rapport au document
  • $(window).scrollTop() : la position verticale du scroll
  • $(window).height() : la hauteur de la fenêtre
Le .offset().top vous retournera 0 si l’élément en question est caché !

Avec seulement ces 3 données, on peut réaliser ce que l’on souhaite. Se pose maintenant la question : à quel moment récupérer ces informations ?

  • au chargement du DOM
  • au scroll
  • au redimensionnement de la fenêtre

Pour pas s’embêter, on sait déjà qu’on va créer une fonction.

Ce que vous attendez tous… la formule magique. Il faut un peu se creuser la tête.

Si la taille de la fenêtre + la position verticale du scroll est supérieure à la position de l’élément (top), alors…

var top = $('#comments').offset().top;
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();

if (windowHeight + scrollTop > top) {
	// ...
}

On peut en faire une fonction check() par exemple puis l’appeler 3 fois :

$(document).ready(function() {
	check();
	
	// quand on scroll
	$(window).scroll(function() {
		check();
	});
	
	// quand on redimensionne
	$(window).resize(function() {
		check();
	});
});

Petite précision, en laissant tel quel, le callback sera déclenché à chaque fois que notre scroll se retrouvera « sous » l’élément puisque la condition sera exécutée. On peut rajouter une variable qui nous permettra de savoir si le callback a déjà été appelé ou non.
Exemple : on initialise une variable loaded à false, on la met à true quand on passe dans la condition et on n’oublie pas de rajouter dans cette condition un !loaded.

Je n’ai pas pu résister à en créer un plugin, que j’ai appelé originalement « desoScroll ». :D
Voici l’appel du plugin :

$(document).ready(function() {
	$('#comments').desoScroll({
		'callback': function(el) {
			el.hide().html('Chargement en cours...').fadeIn(1000);
		}
	});
});

Regardez l’exemple de l’article en démonstration puis si vous êtes intéressés par le code du plugin, rendez-vous sur sa page !

Ceux qui veulent faire la même chose mais avec les images, je vous conseille le plugin Lazy Load.

Vous aimerez aussi...