Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
16 octobre 2008 4 16 /10 /octobre /2008 15:00

Ouvrez grand vos yeux : nous allons reconstruire ensemble le programme reclasseArticles.js dont le mode d'emploi se trouve ici. Le présent article s'adresse aux gens curieux de s'instruire un peu sur JavaScript. Il n'apprendra rien aux connaisseurs et il ne rendra aucun service pour installer le programme, désolé. On continue tout de même ?

Rappelons qu'il s'agit de donner aux articles d'un blog une classe indiquant leur catégorie. Pour commencer, voilà le programme complet :

 function reclasseArticles() { var rArt=document.getElementById('article1'),testReg=/\barticle\b/,i,r,rr,newClass; if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) {rArt=document.getElementById('extraitArticle1');testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; newClass='categorie-aucune'; rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; newClass=r.href.split('\/'); newClass=newClass[newClass.length-1]; newClass=newClass.split('.'); newClass=newClass[0]; break; } rArt.className+=' '+newClass; }while(rArt=rArt.nextSibling); } reclasseArticles(); 

Pour une fois nous n'allons pas désosser le JS une instruction après l'autre mais, au contraire, le construire en l'enrichissant progressivement. C'est d'ailleurs plus proche de la démarche réelle de programmation. Vous voilà prévenu.

Petit cahier des charges

Avant de pisser du code comme un sauvage, il est toujours bon de clarifier ses idées en bon français. Voici ce qu'on attend du programme :

  1. détecter les articles ou les résumés d'articles dans la page affichée,
  2. savoir s'il a affaire à des articles complets ou des résumés,
  3. s'il n'y a ni articles ni résumés, ne pas planter bêtement !
  4. pour chaque article ou résumé, trouver sa catégorie ou son absence de catégorie (article non classé)
  5. enfin, toujours pour chaque article ou résumé, fabriquer le nom de classe correspondant et l'ajouter aux classes déjà attribuées à cet article ou résumé.

Cette petite liste de courses n'a l'air de rien, c'est pourtant elle qu'on pourrait appeler la  spécification  du programme, terme nettement plus classieux. On vérifiera à chaque étape de l'écriture quelles lignes de la liste sont complètement traitées.

Étape 0 : premier jet, premier piège

Ceci est le premier gadget non utilisable au niveau Confiance, le premier qui ne repose pas sur des onclick ou onmouseover, le premier qui s'exécute "à égalité" avec les programmes d'OverBlog et ceux que vous auriez pu déjà installer. Et alors ? Alors on risque des conflits. Si notre JS ressemble à

 var refArticle; var i=0; /* suivi d'un tas de traitements géniaux*/ 
… les variables qu'il déclare (refArticle et i) seront visibles et modifiables par tous les programmes de la page car ce sont des variables globales. À tous les coups il y aura une autre déclaration de i dans un programme déjà en place (si vous saviez le nombre de compteurs de boucle qui s'appellent i…) et le film deviendra soudain très pénible.

Pour éviter ça (qui a dit  plaquette Vapona  ?) nous allons enfermer tout notre traitement dans une fonction, fonction que nous exécuterons ensuite :

 // Ceci (jusqu'à l'accolade fermante) définit la fonction mais n'exécute rien function reclasseArticles() {var refArticle; var i=0; /* suivi d'un tas de traitements géniaux*/ } reclasseArticles(); // Ceci provoque l'exécution de la fonction que nous venons de définir 

Avec cette organisation, refArticle et i sont des variables locales, visibles et modifiables uniquement à l'intérieur de la fonction, dépourvues de signification à l'extérieur : l'extérieur ne peut pas perturber ce qui se passe dans la fonction. Symétriquement, s'il existe déjà une variable globale nommée i, elle sera invisible à l'intérieur de la fonction qui ne connaît que son i local, à usage exclusivement interne : la fonction ne peut pas perturber ce qui se passe à l'extérieur. Ouf !

Voilà pourquoi il est prudent d' emballer  dans une fonction les traitements qu'on se propose de réaliser, puis de déclarer au début de cette fonction toutes les variables qu'on se propose d'y utiliser : on évite ainsi de créer des variables globales, ouvertes à tous les vents.

Cette importante précaution prise, occupons-nous du vrai boulot.

Étape 1.0 : comment trouver les articles ou résumés d'article ?

Les articles ou résumés sont des éléments div. Première idée : récupérer tous les div de la page de blog, ou au moins ceux de la cellule appropriée (cl_1_0, cl_1_1 ou cl_1_2 selon la config du blog) puis les passer en revue pour ne traiter que les bons. Mais il peut y avoir beaucoup de div dans cette cellule (sans parler de la page de blog au complet). Le premier article est sans doute près du début de liste, rien ne garantit que les suivants en seront proches. On peut donc s'attendre à devoir examiner presque tout et ce peut être long.

Aussi ai-je utilisé une autre technique, plus tarzanesque, de saut d'une branche à la suivante dans l'arborescence du document. La grrrrande aventure.

Étape 1.1 : trouver le premier article ou résumé d'article

Pour ça, je m'appuie sur ce que je sais du HTML d'OverBlog : le premier article porte l'identifiant article1 ou bien, si l'on est sur la page propre à l'article (avec ou sans ses comms) l'identifiant articleSeul, ou encore, si l'article est résumé, l'identifiant extraitArticle1. Pour trouver ce premier article ou résumé nous allons tester successivement ces trois possibilités :

 function reclasseArticles() { var rArt=document.getElementById('article1'); // déclare rArt et lui donne une valeur initiale if (!rArt) rArt=document.getElementById('articleSeul'); // si pas de article1 on essaie articleSeul if (!rArt) rArt=document.getElementById('extraitArticle1'); // si ni l'un ni l'autre on essaie extraitArticle1  /* suivi d'un tas de traitements géniaux*/ } reclasseArticles(); 

Bon début, mais n'oublions pas que ce JS s'exécutera sur toutes les pages du blog, or certaines ne comportent ni article ni résumé : liste complète des articles, CGU du blog, "pages" au sens OB du terme… Il faut donc prévoir ce cas-là aussi :

 function reclasseArticles() { var rArt=document.getElementById('article1'); if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) rArt=document.getElementById('extraitArticle1'); if (!rArt) return; // abandon si 1er article introuvable /* suivi d'un tas de traitements géniaux*/ // on n'entame ces traitements qu'à coup sûr } reclasseArticles(); 

Autrement dit : si les trois tentatives pour trouver le premier article ou résumé échouent la fonction ne fait rien : voilà déjà pour le point 3 de la liste de courses.

Petite observation méthodologique : à ce point du développement la fonction, de toute manière, ne produit rien (ça va changer) ! Elle ne produit rien mais elle le produit proprement : sa syntaxe est bien sûr correcte mais, surtout, toutes les réponses possibles à la question posée (= comment trouver le premier article ?) sont envisagées, même et surtout les cas  sans intérêt  (ici, l'absence d'article).

D'abord fabriquer un cadre sûr et complet, ensuite seulement le remplir : voilà un principe d'écriture dont je me suis toujours trouvé bien, plutôt que de rédiger d'abord et ajouter les sécurités ensuite. Vous avez peut-être appris, autrefois, qu'il fallait faire un plan avant de rédiger ? C'est exactement pareil.

Autre observation pour la suite : selon que tel ou tel if réussit ou échoue, nous savons si nous avons affaire à des articles complets ou à des résumés. Pour l'instant nous n'avons pas approfondi la question, ça viendra bientôt.

Étape 1.2 : trouver les articles suivants – premiers pas

Tarzan entre en scène.

L'article ou les articles se trouvent dans un div qui n'a ni identifiant ni classe et, de plus, peut aussi contenir autre chose que des articles, comme le montre cette vue de l'Inspecteur DOM de Firefox :

DOM des articles

Ben oui, c'est mon blog que vous voyez là…

Le rectangle rouge encadre le div sans nom et montre ses  enfants  : l'article (ici unique parce que le blog est configuré en un article par page) et les deux blocs before_articles et after_articles (les paginations) qui sont ses  frères . Nous avons obtenu la référence du premier article, comment progresser dans le rectangle ? C'est prévu, tout élément connaît la référence de son  frère  suivant : ref.nextSibling – tout comme ref.previousSibling est celle du  frère  précédent. Si le frère suivant (ou précédent) n'existe pas, ces références sont nulles.

Nous avons là de quoi faire une jolie boucle pour parcourir la chaîne :

 function reclasseArticles() { var rArt=document.getElementById('article1'); if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) rArt=document.getElementById('extraitArticle1'); if (!rArt) return; do { /* le traitement d'un article ou résumé*/  } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Je vous assure que c'est correct, cependant ça peut dérouter : c'est quoi, ce do ? Et ce test idiot à la fin, comme si un article (ou résumé) pouvait être égal à son successeur ? Allons-y progressivement :

  1. cette boucle est d'un type nouveau : do {/* quelque chose*/} while(/*une condition*/); : on fait quelque chose et, à la fin, on teste. Si le test réussit on recommence le /*quelque chose*/, sinon on termine la boucle et on passe à la suite. D'accord ? Remarquez qu'on ne teste qu'après avoir exécuté le /*quelque chose*/, ce qui signifie qu'on l'exécute au moins une fois.
  2. le test n'est pas ce que vous croyez peut-être : on ne teste pas que rArt est égal à rArt.nextSibling. Vous avez raison de croire que c'est idiot, mais ce n'est pas ce qui est écrit. Ce test idiot s'écrirait rArt==rArt.nextSibling, avec deux signes  égale . Ah ? Il y a ici un seul signe  égale  : ce n'est pas une expression logique (vraie ou fausse), c'est une affectation : on met dans rArt la valeur de rArt.nextSibling. Et le while teste le résultat de cette affectation, c'est-à-dire la nouvelle valeur de rArt.

Redisons-le en français courant : on part du premier article (de référence rArt déterminée par la série de if du début), et on le traite. Une fois l'article traité on change la valeur de rArt – qui désormais désigne le successeur de l'article qu'on vient de traiter. On teste dans le while cette nouvelle valeur de rArt : si l'article qu'on vient de traiter (l'ancien rArt) avait bel et un bien un successeur, le nouveau rArt n'est pas nul et on peut recommencer la boucle. Si l'article qu'on vient de traiter n'avait pas de successeur le nouveau rArt est nul et la boucle se termine.

Vous avez le droit de relire ce paragraphe en suivant le code du doigt pour comprendre la mécanique…

Étape 1.3 : trouver les articles suivants – version complète

La boucle que nous venons de construire parcourt la  descendance  du rectangle rouge à partir du premier article. Mais certains descendants (certains des successeurs du premier article ou résumé) ne sont ni des articles ni des résumés : after_articles, par exemple. Il faudra donc vérifier la classe de rArt avant de plonger dans le traitement :

 function reclasseArticles() { var rArt=document.getElementById('article1'); if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) rArt=document.getElementById('extraitArticle1'); if (!rArt) return; do { if (!/\barticle\b/.test(rArt.className)) continue; // je ne parle que d'article. Les résumés pour plus tard. /* le traitement d'un article ou résumé*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Le test sur className utilise une expression régulière pour trouver le  mot  a-r-t-i-c-l-e au sein de la longue chaîne "article article_even" (explications plus détaillées dans la  dissection  de cet article). Si le mot est absent, la boucle avance d'un cran.

Mais il y a un piège supplémentaire : dans le source HTML, entre la balise </div> qui clôt un article et la balise <div> qui ouvre le suivant, il y a des espaces, des sauts de ligne… bref du texte. Vide mais réel. Qui produit des éléments vides, intercalés entre les autres, et l'Inspecteur DOM de Firefox peut aussi les montrer quand on le lui demande :

DOM des articles, montrant les noeuds vides

Ça fait du monde. La boucle, naturellement, examine aussi ces éléments vides – seulement il y a un os : ils n'ont pas de classe et, du coup, le navigateur proteste (peut protester) quand on lui demande d'appliquer une expression régulière à quelque chose qui n'existe pas. Protester, façon de parler : il se croise les bras et termine abruptement l'exécution de la fonction.

Pour éviter ça (qui a dit… ?) il faut donc, avant d'examiner la classe, vérifier qu'il existe bien une classe à examiner. Pour cela on ajoute un test d'existence avant le test de valeur :

 function reclasseArticles() { var rArt=document.getElementById('article1'); if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) rArt=document.getElementById('extraitArticle1'); if (!rArt) return; do { if (!rArt.className) continue; // pas de classe ? inutile d'insister if (!/\barticle\b/.test(rArt.className)) continue; /* le traitement d'un article ou résumé*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Petit fignolage, les deux tests sur la classe peuvent se regrouper en un seul :

 if (!rArt.className || !/\barticle\b/.test(rArt.className)) continue; 

En français courant :  S'il n'y a pas de classe OU (symbole ||) si cette classe ne contient pas le mot "article", on saute en fin d'itération . Résultat :

 function reclasseArticles() { var rArt=document.getElementById('article1'); if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) rArt=document.getElementById('extraitArticle1'); if (!rArt) return; do { if (!rArt.className || !/\barticle\b/.test(rArt.className)) continue; // Les résumés attendront encore un peu  /* le traitement d'un article ou résumé*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Objection, votre Honneur : s'il n'y a pas de classe, la deuxième moitié du test ne va-t-elle pas faire planter le schbintz, comme vous l'expliquâtes il y a peu ? Toute bonne question mérite réponse.

L'énoncé "A ou B" est vrai si au moins l'un des deux est vrai, d'accord ? L'interpréteur JavaScript, qui lit de gauche à droite et qui est une grosse feignasse, en déduit que : "Si A est vrai, j'ai ma réponse et je ne regarde même pas B". Pour faire riche, on parle de short circuit evaluation. Dans le cas d'espèce : s'il n'y pas de classe (si A est vrai) on ne prendra pas la peine de regarder si elle contient le mot "article" (de regarder si B est vrai), et donc on ne prendra pas le risque de faire sauter la baraque. Voilà : c'est un peu subtil mais bon à retenir.

Étape 2 : et les résumés d'article, alors ?

Il est temps d'y penser. Un résumé d'article porte la classe extraitArticle au lieu de article. Ainsi l'expression régulière utilisée pour tester la classe doit varier. Donc on commencera par la stocker dans une variable (merveilleuse cohérence du jargon !) :

 var testReg=/\barticle\b/; 

Quand faudra-t-il changer sa valeur ? Quand on sera certain que la page ne contient pas d'article, c'est-à-dire après les deux tests sur article1 et articleSeul. Et quand faudra-t-il l'utiliser ? Là où on utilisait /\barticle\b/ en toutes lettres. Concrètement :

 function reclasseArticles() { var rArt=document.getElementById('article1'), testReg=/\barticle\b/; // déclare la variable contenant l'expression régulière if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) { // les deux essais 'articles' ayant échoué, // on ne peut avoir affaire qu'à des résumés rArt=document.getElementById('extraitArticle1'); testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; // ce test vaut pour des articles comme pour des résumés /* un exemple de traitement d'article : */ alert("Nous en sommes à l'article "+rArt.id); } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Cette fois, la boucle est vraiment une boucle sur les articles (ou résumés), tous les articles (ou résumés) et eux seulement. Pour la peine, j'ai mis un embryon de traitement : une boîte de dialogue affichant l'identifiant de l'article (ou résumé). Essayez donc sur une copie locale d'une page de blog, vous verrez que ça marche. Grisant, non ?

On peut maintenant cocher les 3 premiers points de la liste de courses : ça avance !

Étape 3.1 : où est la catégorie d'un article ?

On approche enfin du vif du sujet. La catégorie est (sous une forme ou une autre) dans le lien de classe linkTopic, lequel se trouve en tête ou pied d'article, selon la configuration. De plus, le div où il se trouve porte une classe différente selon qu'on a affaire à un article ou un résumé. Pour récupérer ce lien, le plus simple est donc de ramasser tous les liens de l'article et faire le tri ensuite. Rares (je pense) sont les articles contenant cent liens ou plus, ce ne devrait donc pas être d'une exécution trop longue. Et c'est parti pour une nouvelle boucle à l'intérieur de la précédente :

  1. ramasser tous les liens de l'article :
     var rr; rr=rArt.getElementsByTagName('a'); // rr est un tableau contenant toutes les références demandées 
  2. construire une boucle parcourant ce tableau :
     var i,r; for(i=0;r=rr[i];i++) {/* traitement du lien de référence r*/ } 
    Ça, c'est une boucle for avec ses trois composants :
    • i=0 initialisation - exécutée une seule fois, lors de l'entrée dans la boucle ;
    • r=rr[i] ça, c'est d'abord une affectation (qui définit r) et ensuite un test sur la valeur de r (nulle ou pas), lequel test décide d'exécuter le corps de boucle ou de laisser tomber ;
    • i++ ça, c'est l'instruction qui s'exécute en fin de corps de boucle : incrémenter le compteur (l'augmenter de 1), ce qui fera passer à l'élément suivant dans le tableau (ou à 'vide' lorsqu'on atteint la fin du tableau).
  3. dans le corps de boucle, ajouter un test sur la classe du lien pour ne traiter que linkTopic :
     var rr,i,r; // au passage, je fusionne les deux instruction var rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; // Nota : même technique de test que pour la classe de l'article /* traitement du lien linkTopic */ } 

Ça va toujours ? Petit fignolage : lorsqu'on aura trouvé le lien linkTopic, il sera inutile de parcourir le tableau rr jusqu'au bout :

 var rr,i,r; rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; /* traitement du lien linkTopic */ break; //termine prématurément l'exécution de la boucle for } 

Allez, maintenant on insère ce bout de code dans l'ébauche précédente :

 function reclasseArticles() { var rArt=document.getElementById('article1'),testReg=/\barticle\b/, rr, i, r; if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) {rArt=document.getElementById('extraitArticle1'); testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; /* traitement du lien linkTopic */ break; } /* fin du traitement de l'article rArt*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Étape 3.2 : et si l'article n'a pas de catégorie ?

C'est bien, vous pensez à tout :-).

Si l'article n'est pas classé il n'y a pas de lien linkTopic, donc la boucle sur rr ira à son terme sans rien trouver, et sans jamais exécuter le /* traitement du lien linkTopic */ que nous finirons bien par programmer lui aussi.

Bon. Que faire de cette brillante analyse ? Réfléchissons et anticipons un peu : la /* fin du traitement de l'article rArt */ va consister à ajouter une classe à l'article. Cette classe qu'on ajoute se présentera sous la forme d'une chaîne de caractères, appelons-la newClass. S'il y a une catégorie, le /* traitement du lien linkTopic */ va calculer une valeur pour newClass. Donc s'il n'y a pas de lien linkTopic, la variable newClass ne sera pas modifiée.

Et voilà la solution : lors du traitement d'un article, et avant de partir à la recherche du lien, on postulera que l'article n'a pas de catégorie et on réglera newClass en conséquence. Traduction en JavaScript :

 function reclasseArticles() { var rArt=document.getElementById('article1'),testReg=/\barticle\b/, rr, i, r, newClass; if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) {rArt=document.getElementById('extraitArticle1'); testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; newClass='categorie-aucune'; // on se prépare au pire ! rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; /* calcul de newClass à partir du lien linkTopic */ break; } /* application de newClass à l'article ou résumé rArt*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

Vous saisissez le mécanisme ? Les changement des commentaires reflètent la clarification de nos idées.

Étape 4 : exploiter le lien linkTopic (sous-titre : Massacre à la tronçonneuse)

Ahhhh, enfin ! La catégorie se trouve dans le href de ce lien : http://gnagna.gnigni/categorie-123456.html. Le récupérer, éliminer tout ce qui précède le dernier slash et tout ce qui suit le dernier point : tout cela est déjà présenté en détail dans de précédents articles. Reportez-vous y, c'est de la très bonne littérature ! Voilà en tout cas le résultat :

 newClass=r.href.split('\/'); // rappel : r est la référence du lien. Ici on découpe le href selon les slash newClass=newClass[newClass.length-1]; // on récupère le dernier tronçon newClass=newClass.split('.'); // on le découpe selon les points (normalement, il n'y en a qu'un) newClass=newClass[0]; // le premier morceau contient categorie-123456 

Quoique… je vous ai déjà parlé de la méthode split ? C'est simple : elle prend une chaîne, la découpe aux endroits où apparaît le caractère de séparation (qui peut être une chaîne, d'ailleurs) et range les tronçons dans un tableau. newClass est le résidu ultime de ces découpages successifs.

Allez, on met ça en place dans le code déjà écrit :

 function reclasseArticles() { var rArt=document.getElementById('article1'),testReg=/\barticle\b/, rr, i, r,newClass; if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) {rArt=document.getElementById('extraitArticle1'); testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; newClass='categorie-aucune'; // on se prépare au pire ! rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; newClass=r.href.split('\/'); newClass=newClass[newClass.length-1]; newClass=newClass.split('.'); newClass=newClass[0]; // cette fois on brûle ! break; } /* application de newClass à l'article ou résumé rArt*/ } while(rArt=rArt.nextSibling); } reclasseArticles(); 

À ce stade, on peut cocher la ligne 4 de la liste de courses.

Étape 5 : ajouter newClass à l'article

Ça, c'est le plus simple. La classe de l'article ou résumé en cours de traitement est rArt.className, nous le savons depuis un moment. Pour lui ajouter la valeur de newClass que nous venons de calculer, il ne faut surtout pas écrire

 rArt.className=newClass; 
… qui remplacerait toute la séquence article article_odd par la nouvelle valeur ! Il faut ajouter newClass à la fin de rArt.className, en laissant un espace d'intervalle :
 rArt.className=rArt.className+' '+newClass; 

Cela peut s'écrire de façon plus ramassée :

 rArt.className+=' '+newClass; 

Ne reste plus qu'à mettre cette instruction à la bonne place  :

 function reclasseArticles() { var rArt=document.getElementById('article1'),testReg=/\barticle\b/, rr, i, r,newClass; if (!rArt) rArt=document.getElementById('articleSeul'); if (!rArt) {rArt=document.getElementById('extraitArticle1'); testReg=/\bextraitArticle\b/;} if (!rArt) return; do { if (!rArt.className || !testReg.test(rArt.className)) continue; newClass='categorie-aucune'; // on se prépare au pire ! rr=rArt.getElementsByTagName('a'); for (i=0;r=rr[i];i++) { if (!r.className || !/\blinkTopic\b/.test(r.className)) continue; newClass=r.href.split('\/'); newClass=newClass[newClass.length-1]; newClass=newClass.split('.'); newClass=newClass[0]; break; } rArt.className+=' '+newClass; } while(rArt=rArt.nextSibling); } reclasseArticles(); 
… qui n'est rien d'autre que le programme donné au début de cet article.

Cochez la dernière ligne de la liste de courses, nous venons de reconstituer le programme, sans magie noire, en expliquant tout – et peut-être en le comprenant…

Et vous savez quoi ? Une fois que ce code est en service et la page de blog complètement chargée, l'examiner avec l'Inspecteur DOM (je l'aime, celui-là) montre la nouvelle classe innocemment mentionnée près de l'article, à la suite des autres, exactement comme si elle avait été écrite  en dur  par OverBlog à la suite des demandes insistantes des blogueurs… Pas beau, ça ?


Ça vous a plu ? Alors vous allez adorer styler les pages selon leur URL.


À toutes fins utiles : quelques bonnes adresses pour en savoir plus sur JavaScript.

commentaires

Archives