Poser ses matières sur la table avec jquery

J’ai commis l’erreur que beaucoup ont commis avant moi, à savoir utiliser un plugin wordpress pour quelque chose qui s’est avéré somme toute assez simple : Générer dynamiquement une table des matières à partir des titres, pour un contenu qui peut être long. Je l’avais utilisé pour l’article sur Tiny Issue. Alors qu’en fait, cela peut se faire en quelques lignes de javascript.

Pour commencer, il faut décider sur quels éléments on va créer la table des matières. A savoir : titres de niveau 1, éléments avec une certaine classe, … ? J’ai choisi pour ma part que chaque titre de niveau 1 à l’intérieur de mon div de classe article-content devait générer une entrée.

Commençons par le code html. J’ai préparé un conteneur pour réceptionner les entrées de menu, conteneur que j’ai masqué en css pour le moment :

<ul class="page-sub-menu"></ul>

Maintenant, le javascript. Je vais logiquement commencer par :

$(".article-content h1").each(function(){  });

Si j’avais décidé que tous les h1, h2 et h3 devaient être de la partie :

$("h1, h2, h3").each(function(){  });

Maintenant que faire ? Voici le code complet:

$(".article-content h1").each(function(i) {
	$(".page-sub-menu").css({"display":"block"});
	var current = $(this);
	current.attr("id", "title" + i);
	$(".page-sub-menu").append("<li><a id='link" + i + "' href='#title" +
		i + "' title='" + current.html() + "'>" +
		current.html() + "</a></li>");
});

Que se passe-t-il? Dans l’ordre, ligne par ligne :

  • Pour chaque h1 de mon conteneur de classe article-content
  • J’affiche le conteneur de mon menu, de classe page-sub-menu
  • Je stocke l’élément courant, pour plus de simplicité
  • Je défini que l’élément courant, le titre dans mon contenu, aura comme id le mot « titre » suffixé par un numéro qui s’incrémente à chaque nouveau titre trouvé
  • J’ajoute au conteneur du menu une nouvelle ligne avec un lien qui cible le titre auquel je viens de donner un id

J’ai ajouter ci et là des informations de titre et autre pour plus de clarté, mais l’essentiel est dit. Ça y est, on a notre menu. Pour le fun j’ai ajouté aussi quelque chose qui permet de se rendre à notre titre avec un scroll tout smooth :

$(".page-sub-menu li a").click(function(event){
	event.preventDefault();
	var full_url = this.href;
	var parts = full_url.split("#");
	var trgt = parts[1];
	var target_offset = $("#"+trgt).offset();
	var target_top = target_offset.top;
	$('html, body').animate({scrollTop:target_top}, 500);
});

On pourrait même pousser le bouchon pour rendre ce menu sticky si on scroll dans l’écran, pour toujours l’avoir sous la main :

D’abord un peu de CSS sur une classe page-sub-menu-fixed :

.page-sub-menu-fixed{
	z-index: 999999;
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	text-align: center;
	border-radius: 0px;
	-moz-border-radius: 0px;
	-webkit-border-radius: 0px;
}

Puis au scroll on rajoute la classe ou en l’enlève, selon le cas :

$(window).scroll(function(){
var scrolltop = $(document).scrollTop();
scrolltop = scrolltop + 250;
if(scrolltop &gt; 500){
$('.page-sub-menu').addClass('page-sub-menu-fixed');
}
if(scrolltop &lt; 500){
$('.page-sub-menu').removeClass('page-sub-menu-fixed');
}
});

Voilà, j’espère que tout le monde est au point !

3 commentaires

  1. Merci pour l’astuce, le scroll en animate est parfait mais
    un petit lien d’exemple serait idéal pour les flemmard ds mon genre !!!

    sinon [mode coquille on] > « On pourrait même pousser le bouchon pour rendre ce menu sticky si on scroll dans l’acran, pour oujours l’avoir sous la main : »

    tu mets oujours tes doigts sale sur l’acran 😉

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *