Toi aussi, épâte tes amis avec une navigation par volet à la SundayMorning
Posé ici le vendredi 18 décembre 2009 à 14:04 par
Si vous êtes un habitué de ce blog, le nom de SundayMorning devrait vous être familier. C'est l'un de mes projets Open Source de l'année dernière. Ce projet est né de quelques idées que j'avais précédemment ébauchées ici et là.
Lors de la réalisation du site web, je voulais m'éloigner de l'aspect ennuyeux que pouvait engendrer la navigation au sein de la documentation. J'ai donc proposé le contenu en une seule page mais en le fractionnant en plusieurs volets coulissants.
Cet effet a manifestement attisé la curiosité de quelques uns d'entre-vous. Je leur avais promis par email d'en parler un jour. C'est maintenant, Joyeux Noël !
MISE A JOUR Samedi 2 Janvier 2010 : Cet article a été mis a jour. J'ai ajouté le retour en haut de page de la scrollbarre du navigateur à chaque ouverture de volet.
Let's begin
Comme à mon habitude, je pars d'une portion de code la plus sémantique et neutre possible. La mise en forme et les effets n'arriveront que par la suite.
<div id="container">
<div class="section">
<h2>Première section</h2>
<p>Aliquam convallis sollicitudin purus....</p>
</div>
<div class="section">
<h2>Deuxième section</h2>
<p>Egestas sed, gravida nec, ornare ut, mi...</p>
</div>
<div class="section">
<h2>Troisième section</h2>
<p>Aliquam convallis sollicitudin purus...</p>
</div>
<div class="section">
<h2>Quatrième section</h2>
<p>Egestas sed, gravida nec, ornare ut, mi...</p>
</div>
<div class="section">
<h2>Cinquième section</h2>
<p>Aliquam convallis sollicitudin purus...</p>
</div>
</div>
On n'aurait pu faire encore plus neutre en évitant la classe .section, mais le tutoriel aurait peut-être été moins clair.
Mise en forme
Voici la feuille de style. A l'exception de quelques points, modifiez la selon vos besoins, c'est affaire de goût.
body {
background: #3344FF;
color: #FFF;
font: 12px Arial, Helvetica, sans-serif;
}
#container {
position: fixed;
right: 0;
top: 0;
}
.section {
background: #3366FF;
color: #FFF;
float: left;
height: 1000px;
padding: 10px;
width: 200px;
}
a.more, a.close {
color: #CCFF00;
display: block;
font-weight: bold;
text-decoration: none;
}
Les points importants et nécessaires à la bonne marche de l'effet sont les suivants :
#container {
position: fixed;
right: 0;
top: 0;
}
.section {
float: left;
height: 1000px;
width: 200px;
}
Le container est passé en position fixe en haut à droite de l'écran. Chaque section est placée en colonne flottante de 200px sur 1000px (histoire de couvrir toute la largeur de l'écran). On en arrive à ce résultat :
Le script jQuery
Pour ne pas changer, jQuery nous aidera à la tâche. Une fois la librairie inclue, procédons étape par étape.
var n = $(".section").size();
var w = $(".section").eq(0).outerWidth();
Il est nécessaire de récupérer quelques valeurs importantes. Ici n est le nombre de sections, w leur largeur. On part du principe que toutes les colonnes ont la même largeur.
$('#container').css({
width: n * w,
right: -(n * w) + w
});
A partir des valeurs précédemment récoltées, on ajuste le container et on le place de manière à ce que seul le premier volet soit visible.
Les volets
Attaquons-nous aux divers volets :
$('.section')
.append('<a href="#" class="close">Fermer</a> <a href="#" class="more">Suivant</a>')
.hide();
Tous les volets sont masqués. On y ajoute dynamiquement les liens Fermer et Suivant.
$('.section:first')
.show()
.find('.close')
.remove();
Le premier volet doit être visible dès le départ et ne jamais disparaitre. On le réaffiche donc et on lui supprime son lien Fermer inutile.
$('.section:last')
.find('.more')
.remove();
Le dernier volet ne doit pas avoir de lien Suivant. On le supprime. Si tous les volets était visibles, on obtiendrait ceci :
Lien Suivant
Occupons-nous du lien Suivant.
$(".section .more").click(function() {
$(this).hide();
var next = $(this).parent('.section').next();
openIt(next);
return false;
});
Lorsque ce lien est cliqué, on le masque car il ne sert plus tant que le volet suivant est affiché. On sélectionne ensuite le volet suivant que l'on passe à la fonction openIt() qui se chargera de l'animation de son affichage. Voici cette fonction :
function openIt(section) {
if ($(section).is(':visible')) {
return false;
}
$("#container").animate({ right:'+=' + w + 'px' }, function() {
section.fadeIn(function() {
$('html,body').animate({scrollTop: 0}, 900);
});
});
}
Ici, on s'assure que le volet en question n'est pas déjà visible. Si c'est le cas, on passe notre chemin. Sinon, affichons-le dans un doux effet fadeIn(), suivi du retour de la barre de scrolling en haut de page. Auparavant, on déplace le container en en réduisant la marge right de la largeur d'une section (w).
Lien Fermer
Pour le lien Fermer, la logique est quasiment identique :
$(".section .close").click(function() {
var prev = $(this).parent('.section').prev();
$('.more', prev).show();
var current = $(this).parent('.section');
closeIt(current);
return false;
});
On réaffiche le lien Suivant du volet précédent et on appelle la fonction closeIt() qui masquera le volet courant.
function closeIt(section) {
section.fadeOut(function() {
$("#container").animate({ right:'-=' + w + 'px' });
});
}
Même chose ici que pour openIt(), mais à l'envers. On fait un fadeOut() et on déplace le container en jouant sur la marge droite à laquelle on déduit la largeur d'un volet (w).
Ce n'est pas plus compliqué que ça.
L'intégralité du code
Pour y voir plus clair, voici le code dans son ensemble :
/**
* Navigation à la Sunday Morning
* sur http://sundaymorning.jaysalvat.com/
* par Jay Salvat - http://blog.jaysalvat.com/
*/
$(function() {
var n = $(".section").size();
var w = $(".section").eq(0).outerWidth();
$('#container').css({
width: n * w,
right: -(n * w) + w
});
$('.section')
.append('<a href="#" class="close">Fermer</a> <a href="#" class="more">Suivant</a>')
.hide();
$('.section:first')
.show()
.find('.close')
.remove();
$('.section:last')
.find('.more')
.remove();
$(".section .more").click(function() {
$(this).hide();
var next = $(this).parent('.section').next();
openIt(next);
return false;
});
$(".section .close").click(function() {
var current = $(this).parent('.section');
closeIt(current);
var prev = $(this).parent('.section').prev();
$('.more', prev).show();
return false;
});
function openIt(section) {
if ($(section).is(':visible')) {
return false;
}
$("#container").animate({ right:'+=' + w + 'px' }, function() {
section.fadeIn(function() {
$('html,body').animate({scrollTop: 0}, 900);
});
});
}
function closeIt(section) {
section.fadeOut(function() {
$("#container").animate({ right:'-=' + w + 'px' });
});
}
});
Conclusion
L'effet étant unique, il ne m'a pas semblé utile d'en faire un plug-in. Pourtant l'exercice pourrait être sympa à réaliser pour des besoins plus récurants. En le présentant ainsi par exemple :
$('#container').slideNav({
children: '.section',
moreClass: '.more',
moreText: 'Suivant',
closeClass: '.close',
closeText: 'Fermer'
});
Les plugins jQuery n'ayant plus aucun secret pour vous, ça ne devrait pas vous faire peur. Je relève les copies dans une heure.
Ce contenu est mis à disposition selon les termes de la licence Creative Commons 2.0 France : Paternité, Pas d'Utilisation Commerciale, Partage des Conditions Initiales à l'Identique.
Context
Thématiques :
Trackbacks
0 trackback



Commentaires
4 commentaires
Pas forcément constructif, ce commentaire sera néanmoins courtois et - je l'espère - correctement écrit.
Je voulais simplement féliciter. Féliciter l'idée, l'auteur, le concept en lui-même. Très utile, très esthétique, résolument tourné vers le Web "nouvelle génération". Cela donne un aspect plutôt interactif que je recherche personnellement particulièrement sur les sites que je visite.
Je pense que nous (mon équipe et moi-même) insèrerons éventuellement ce petit bijou sur notre site pour "épater nos amis".
Je vais, je pense, sérieusement me pencher sur l'utilité d'une telle option dans le projet que nous menons. Si nous le faisons, nous ne manquerons pas de faire un lien vers "chez vous" :)
Dans tous les cas bravo, le travail est admirable.
Cordialement,
Shina.
1. Par Shina le vendredi 18 décembre 2009 à 17:18
Très bon tuto. Merci
2. Par Yoan le vendredi 18 décembre 2009 à 20:49
Original, et très explicite.
Bonne fête de fin d'année et meilleur vœux pour 2010
3. Par Djb le samedi 19 décembre 2009 à 03:31
Long time ago I found sunday-morning and the site navigation amazed me more than the plugin itself.
Thanks for the time to write down the how to: I will definetly put it into use.
In short, thanks for sharing (sorry, my french is bad, can read it but not write it).
4. Par Pol Moneys le samedi 01 mai 2010 à 13:54