Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
26 mars 2007 1 26 /03 /mars /2007 03:07
(article revu en août 2008 : simplification de la technique employée et correction du lien vers PêUR)

L'idée originale vient de cet article de PêUR, avec quelques perfectionnements mineurs dans le présent article et dans le suivant.

Rien de très difficile et, s'il ne s'agissait que de livrer la recette, vous ne liriez qu'un plagiat. Seulement mon intention n'est pas de fournir un poisson mais d'apprendre à pêcher : on va faire comme si on inventait la solution nous-mêmes au lieu de la repiquer toute prête, et je m'efforcerai d'expliquer tous les choix techniques au passage. Plus long mais plus instructif, je trouve.

Mais si décidément JavaScript vous effraie trop voici aussi une solution en pur CSS, plus limitée mais bien plus simple, qui vous suffira peut-être.

Notes :

  • PêUR ayant eu la grande gentillesse de signaler cet article, vous êtes assez nombreux à le lire ces derniers temps. Votre avis m'intéresse, vous savez ? Est-ce utile ? clair ? trop long ? trop fouillé ? pas assez (hum…) ? Mêmes questions d'ailleurs pour chaque papier technique : utile ? instructif ? rasoir ? Dites-moi, je suis preneur !
  • Cette technique n'est pas réservée aux blogs OverBlog.
  • Chez OverBlog, elle est utilisable dès le niveau  Confiance .
  • Vous pouvez bien sûr faire un copier-coller bestial du code, en négligeant les explications. Mais j'aime bien comprendre ce que je fais, pas vous ? Faites-moi donc plaisir : revenez lire le topo à tête reposée quand vous aurez victorieusement greffé le gadget chez vous.

Préambule : HTML, CSS, JavaScript en quelques mots

Du simple au compliqué.

Une page HTML, c'est d'abord du texte. Preuve : créez avec le bloc-notes un fichier de texte tout simple (ni balises ni rien de spécial), ouvrez-le avec le navigateur : ça marche. Certes c'est vilain, brut de décoffrage, mais ça marche.

Le langage HTML permet d'organiser ce texte en blocs : paragraphes ou listes ou autres. Il permet d'y ajouter des titres, des références à des images (pas les images elles-mêmes) ou à d'autres pages HTML (pas ces pages elles-mêmes), tout ceci par l'emploi de balises. Un progrès : c'est organisé. Mais ça reste brut d'aspect.

Le langage CSS permet de préciser la présentation de ce texte organisé : polices de caractères, couleurs, disposition, etc. Nouveau progrès : c'est organisé et, en plus, (on espère que) c'est joli à regarder.

Analogie avec le papier : HTML c'est la rédaction (machine à écrire), CSS la mise en page (colle et ciseaux). Mais le résultat reste essentiellement statique, à part les effets obtenus au survol de certains éléments (pseudo-classe :hover) : HTML et CSS sont des langages de présentation, pas de programmation – ce qui n'est nullement une tare.

Animer ce paysage demande d'autres outils, leur catalogue est épais. Les uns agissent sur le serveur mais ils ne sont pas disponibles au niveau  Confiance , donc nous ferons l'impasse dessus. Les autres agissent sur le client (=votre navigateur). Le plus utilisé de ces langages  à faire bouger le navigateur  s'appelle JavaScript – nous y voilà.

Maintenant, on va penser…

Résultat

Voilà donc le bébé, à ne pas recopier en l'état :

 <p>Début de l'article</p> <a href="#escamotable" onclick=" /* Petit gestionnaire d'événements. Vous êtes en train de lire un commentaire JavaScript à la syntaxe furieusement proche de celle du CSS. */ document.getElementById('nom_unique').style.display= ''; /* redonne au div son display 'normal' */ return false; // (ceci est un commentaire en fin de ligne) ">Lire la suite…</a> <div id="nom_unique" style="display:none"> <p>Le texte à cacher</p> </div> 

Pourquoi ne faut-il pas le recopier ? Utilisateurs d'OverBlog, quand vous copiez/collez un Javascript tel que celui-ci, SUPPRIMEZ LES COMMENTAIRES DE FIN DE LIGNE, ceux précédés par //. Pourquoi ? L'éditeur d'articles peut supprimer les caractères de fin de ligne… du coup, le premier commentaire  de fin de ligne  (ici écrit après return false;) se trouve indûment étendu jusqu'à la fin du programme, ce qui n'est pas bon du tout ! Voici donc le bébé définitif, copiable en toute sécurité :

 <p>Début de l'article</p> <a href="#nom_unique" onclick=" document.getElementById('nom_unique').style.display= ''; return false;">Lire la suite…</a> <div id="nom_unique" style="display:none"> <p>Le texte à cacher</p> </div> 

Attention encore ! Pensez à remplacer  nom_unique  par quelque chose de vraiment unique dans tout votre blog ! Par exemple en combinant le titre de l'article et un mot désignant la section escamotable de l'article. Exemple ici-même : le corps (escamotable) de l'article s'appelle fairelirelasuite et la  dissection  qui arrive maintenant (escamotable dans l'escamotable) s'appelle lirelasuite_dissection.

Peut-être vous demandez-vous pourquoi l'identifiant doit être unique dans tout le blog ? Bonne question, puisqu'il suffit qu'il soit unique dans la page. Bien sûr (non ?) vous penserez à éviter les identifiants déjà employés par OB, tels que top ou global, donc on pourrait se contenter d'utiliser systématiquementsuite, par exemple. Mais si vous mettez plusieurs sections escamotables dans le même article vous serez mal. D'accord, donc avec suite1, suite2… on s'en sort, non ? Pas sûr : vous avez peut-être configuré votre blog pour afficher plusieurs articles par page, ou vous le ferez un jour. Si deux articles dotés d'un escamotable se retrouvent sur la même page, vous serez mal de nouveau. Donc : unique dans tout le blog, ce n'est pas si difficile et beaucoup plus sûr.


Dissection de la bête

Le gestionnaire onclick est un attribut du lien, tout comme href ou title, et il est syntaxé de la même manière : sa valeur (=le code JS) s'écrit entre guillemets (doubles) après le signe   =   .

Chaque instruction se termine par un point-virgule, même la dernière (restons prudents). Ici, présentation un peu soignée avec marge et retours à la ligne, mais rien n'interdit de tout écrire sur une seule ligne : notre gestionnaire ne comporte, après tout, que deux instructions…

La première est de la forme un_truc = 'chaine_de_caracteres' ; . Les apostrophes simples signalent une constante de type  chaîne de caractères , c'est assez classique en programmation (ici la chaîne est vide, explication bientôt). À gauche du signe  égale , les choses sont plus intéressantes : on indique l'entité (en jargon, l' objet ) à laquelle on affecte cette valeur, et cette entité porte un nom à rallonges. Ici il y a trois rallonges, séparées par des points. De gauche à droite on va du plus large au plus spécifique. Examinons l'assemblage, dans cet ordre :

document
désigne le document HTML chargé dans le navigateur.
Comme beaucoup de ce qu'on manipule en JavaScript se rattache peu ou prou au document, vous comprenez que ce mot figurera très souvent dans un programme JavaScript.
document.getElementById
est une  méthode  du document.
Ce qui veut dire ? En gros, une fonction (une série d'instructions) attachée au document, une manière de cuisiner des données.
Il existe tout un troupeau de telles méthodes, rédigées par les auteurs du navigateur. Tout l'art du programmeur JavaScript consiste à trouver la bonne documentation de référence, et ce n'est pas toujours simple. Laissez la question de côté pour aujourd'hui, faites-moi confiance et continuons.

Le nom de la méthode s'écrit en minuscules. Il se compose ici de quatre mots ("get" "element" "by" "id", mais sans espaces intercalés), le début de chaque mot est marqué par une majuscule sauf le premier. Pas de tiret haut ou bas pour séparer les mots. Ceci n'est pas une norme officielle, juste une convention acceptée par tout le monde ; autant la connaître et la respecter.
Elle fait quoi, cette méthode ? Elle va, dans le document, chercher (get) le morceau de HTML (Element) porteur de l'identifiant (ById) indiqué juste après, entre parenthèses (ce qui est entre les parenthèses s'appelle un  argument  de la méthode). Rappelez-vous : un identifiant est unique dans une page, donc il existe au plus un élément portant ce nom – on accepte l'échec mais pas l'ambigüité.
Quand la méthode a trouvé l'élément, elle en fait quoi ? Elle met à disposition du programme une référence à cet élément, autrement dit un zigouigoui, à usage interne, indiquant à quel endroit de mémoire se trouvent les informations relatives à l'élément (on peut aussi dire  un pointeur , mais c'est devenu un gros mot qui trahit le vieux programmeur démodé). On pourrait le stocker (le zigouigoui, pas le programmeur) dans un coin (= dans une variable) si on devait s'en resservir, mais ce n'est pas le cas ici. Enfin, la méthode getElementById, contrairement à d'autres, ne change rien ni à l'élément ni au document.

document.getElementById('nom_unique')
écrire le nom de la méthode avec des arguments en provoque l'exécution.
Donc  Médor rapporte le nonosse  et voilà : tout comme  document  désignait le document,  document.getElementById('nom_unique')  désigne l'élément nommé  nom_unique .
Cet élément, à son tour, peut porter d'autres méthodes. Il peut porter aussi des informations toutes simples (on parle d'  attributs ) telles que son texte, sa couleur, sa position… encore un troupeau, encore une question de trouver la bonne doc. Continuez à me faire confiance et avançons.
document.getElementById('nom_unique').style
ceci désigne les informations de style attachées à l'élément dans le HTML, c'est à dire par un attribut style="propriété:valeur" s'il y en a un (style  local ).
Ceci ne tient donc aucun compte du style indiqué dans le CSS. Le style effectif de l'élément ( computed style ), celui qui résulte du CSS et de l'éventuel style local, est plus compliqué à obtenir en JavaScript – et hors sujet pour aujourd'hui (ouf !).
document.getElementById('nom_unique').style.display
ceci désigne la propriété display du style local
document.getElementById('nom_unique').style.display = '';
ceci remet la propriété display du style local à  rien  : l'élément revient au display résultant du CSS, quel que soit ce display.

Maintenant, la deuxième et dernière instruction return false;. Le mot return indique qu'on renvoie des informations au navigateur, et ce qu'en fera le navigateur dépend du contexte. Ici, nous sommes dans un lien <a> et cette valeur renvoyée sert à décider de suivre ou non le href du lien. true on le suit, false on ne le suit pas, c'est tout bête.

Déroulement du film

Concrètement, comment tout cela marche-t-il ?

  1. le navigateur charge la page. Pour mettre le div en forme, il suit les indications du CSS et celles du style local éventuel. Le display du div est donc none et le div est caché. Le lien, lui, apparaît comme un brave lien dont rien ne signale qu'il transporte une machine infernale. Bien sûr, on suppose pour la suite que le navigateur accepte de traiter le JavaScript sinon c'est pas drôle.
  2. Tant que l'utilisateur ne fait rien, il ne se passe rien…
  3. … mais SI l'utilisateur clique sur le lien (voilà un événement), le navigateur, voyant le gestionnaire onclick, en commence l'exécution…
  4. … trouve, par la méthode getElementById, les coordonnées du div nommé 'nom_unique'…
  5. … change le style local de ce div et en tire aussitôt les conséquences : le div apparaît. Première instruction terminée.
  6. Deuxième instruction : ne pas suivre le href en sortant. Bon, on ne le suivra pas.
  7. C'est donc fini

Premier perfectionnement

Cliquer sur le lien ne fait qu'une seule chose : révéler le div caché.

Mais le lien continuera de se voir, c'est un peu déroutant. On pourrait vouloir qu'un deuxième clic cache de nouveau le div, que le texte du lien s'adapte aux circonstances, que sais-je encore ? C'est possible mais moins simple, on en reparlera dans le prochain article. Pour aujourd'hui on se contentera de faire disparaître le lien.

Le principe est le même : changer le style local du lien comme on change celui du div. Et soulève donc la même question : comment obtenir la référence du lien ?

On pourrait lui donner la même réponse : donner un identifiant (unique dans tout le blog !) au lien, et vogue la galère du document.getElementById('id_du_lien').style.display='none';

Mais là on peut faire plus simple, parce qu'il s'agit d'intervenir sur l'élément cliqué plutôt qu'ailleurs dans la page. Un raccourci permet d'accéder à cet élément sans l'encombrer d'un identifiant, ce raccourci est le mot this.

En clair, le onclick grossit d'une ligne :

 <p>Début de l'article</p> <a href="#nom_unique" onclick=" document.getElementById('nom_unique').style.display= ''; this.style.display= 'none'; return false;">Lire la suite…</a> <div id="nom_unique" style="display:none"> <p>Le texte à cacher</p> </div> 

Quand on explique c'est plus clair, non ?

Comparaison avec la solution de PêUR

PêUR fait figurer l'identifiant du div dans le CSS et pas moi : dans le principe, déjà, ça m'ennuyait de mentionner dans le CSS (à vocation générale) le traitement d'un article particulier. De plus, tout se complique si, ayant plusieurs articles par page, on veut appliquer la technique à plus d'un article : plus question d'employer un identifiant à tout faire !

PêUR propose d'utiliser alors #cache1, #cache2, etc. et de compléter le CSS en conséquence. Je crains tout de même qu'au fil de la vie du blog (suppression d'articles, changement de catégorie ou de date…) deux articles utilisant le même id ne se retrouvent dans la même page. Pour l'éviter, on peut utiliser un id spécifique à chaque section escamotable de chaque article, ce que je fais d'ailleurs : #fairelirelasuite, #ordremethode5, etc. Mais le CSS deviendrait alors interminable et jamais à jour, d'où le recours à une pure intervention sur le style local.

Autre gain accessoire : puisqu'il n'y aura plus à s'inquiéter du CSS, rien n'empêchera de mettre plusieurs  lire la suite  successifs ou imbriqués dans un même article très long. Ça peut rendre service, voyez donc la  dissection  qui précède !


Pas trop souffert ? Cet article est (nettement) plus long que celui de PêUR, pour une solution à peine retouchée. C'est parce que cette manip', très simple en soi, a servi de prétexte à exposer pas mal de choses, tout le  comment  et le  pourquoi , et j'ai du mal à rester bref en ces matières.

Le prochain article, bientôt, présentera quelques variations autour de ce thème – et il sera plus court !


commentaires

D
Super article, merci pour ces informations precieuses
Répondre
S
<br /> Bonjour,<br /> C'est un super code qui marche. Je viens d'en faire l'expérience sur mon blog. La seule chose qu'on pourrait opposer c'est qu'en édition, il faut appliquer ce code vraiment à la fin de la rédaction<br /> de l'article. Car si on veut faire des modifications par la suite, on ne pourra les faire plus que dans l'html puisque ne s'affiche plus que le "lire la suite". Y-a-t-il une solution pour "ouvrir"<br /> dans le texte en édition le lire la suite ?<br /> Merci encore pour ces codes. Bon samedi. S.33<br /> <br /> <br />
Répondre
A
<br /> <br /> Hé non, il n'y a pas d'autre solution que de passer par le mode HTML : l'éditeur de texte OB prend au pied de la lettre les indications de style ou le JavaScript présents dans le code<br /> source...<br /> <br /> <br /> De là (marotte personnelle...) l'intérêt de conserver le code source de ses articles sur son micro, pour les élaborer en local avec un éditeur de texte tel que Notepad++. Ensuite, je n'utilise<br /> plus que le mode HTML de l'éditeur OB pour un copier-coller bestial.<br /> <br /> <br /> <br />
S
<br /> Bonjour. Ton article est excellent. Je voudrais l'utiliser dans un module-texte de mon blog. Jusqu'ici ça marche. Mais j'aimerais savoir comment masquer de nouveau le texte ! Merci.<br /> <br /> <br />
Répondre
A
<br /> Jusqu'ici ça marche ? Ohhh, c'est encourageant ! :-D<br /> Pour masquer de nouveau le texte : lire l'article suivant ! (et ses commentaires qui contiennent aussi d'autres réponses à d'autres questions)<br /> <br /> <br />
W
http://wolofi.over-blog.com/article-29441750.html
Répondre
W
attends, Petit navire, <br /> <br /> on m'a montée en grade pour quelques jours, je crois, alors je ne voulais pas faire honte: il y avait plein de fine tuning à faire ailleurs. Je réessayerai les interrupteurs et je reviendrai te voir, d'accord? Ce sont les proverbes wolofs qui font souci. Trop de sagesse, c'est pas sain. C'est pourquoi je veux en cacher un bout.<br /> <br /> A +
Répondre
W
Petit Navire,<br /> <br /> Je rame comme c'est pas possible avec ton 2e interrupteur. Juste pour que tu saches pourquoi, toi aussi, tu as mal à la tête. <br /> Petit Vélo
Répondre
A
<br /> Mal à la tête ? Non, pas encore... tu ne vas tout de même pas me marabouter pour un bout de Javascript ? ?<br /> Sinon, plus sérieusement, ça marche tout seul d'habitude... Donne-moi donc une url "à problème" que j'aille y jeter un oeil.<br /> <br /> <br />
W
Petit navire,<br /> <br /> Ça marche pour cacher. Maintenant, je vais apprendre comment faire pour recacher. A plus, <br /> <br /> Petit vélo
Répondre
A
<br /> "Petit navire", j'ai déjà ! "Petit vélo", c'est une idée...<br /> <br /> <br />
W
Bonjour,<br /> <br /> C'est très bien fait, ce cours. Merci pour le temps que tu prends pour nous expliquer les choses. Ça donne envie d'apprendre encore plus et plein de trucs, d'explorer partout. <br /> <br /> 'Lire la suite...' marche en prévisualisation, mais pas dans l'article déjà publié !?!
Répondre
A
<br /> Oh, merci pour le mot aimable ! Donner envie d'explorer, c'est pile le but - bien pour ça qu'il y a des liens un peu partout.<br /> D'après le comm suivant je peux penser que ça marche aussi à l'emplacement normal, maintenant ? :)<br /> <br /> <br />
F
j'utilise un peu ça dans un article test <br /> http://lannexe.over-blog.com/article-28710607.html<br /> mais dans un tableau, impossible de trouver comment afficher/masquer la cellule adéquate, même en reprenant bien l'id du div ... (http://lannexe.over-blog.com/article-28710164.html)<br /> <br /> j'ai toujours des idées tordues de toute manière :D<br /> <br /> <br /> clic pour afficher<br /> <br /> clic pour masquer<br /> <br /> ICI j'ai le reste de ce que je veux voir ou non <br /> <br /> Merci merci pour ces détails précieux ... <br /> me reste plus qu'à trouver le code pour changer (et non ajouter) une feuille css ... j'ai pas fini de galérer.
Répondre
A
<br /> M'en vais regarder ça - trop complexe pour répondre tout de suite<br /> <br /> <br />
S
ça fonctionne super bien, je te remercie pour cet article complet!
Répondre
A
<br /> Ah, un client heureux ! :-D Faut revenir !<br /> <br /> <br />

Archives