Extension du navigateur Organiser les publications Tumblr dans l'ordre chronologique

Créer de petites extensions de navigateur est un excellent moyen d'apprendre le JavaScript. Vous n'avez pas à vous soucier de la compatibilité entre navigateurs, vous pouvez rendre le projet aussi petit ou grand que vous le souhaitez et vous pouvez également résoudre les problèmes des sites Web d'autres personnes qui vous posent problème. Dans cet article, nous allons créer un court script qui réorganise automatiquement les pages d'archives de Tumblr pour qu'elles soient lues dans un ordre chronologique - et nous en apprendrons davantage sur NodeList en chemin.


Le problème

Cette semaine, Ryan North a lancé un nouveau Tumblr dans lequel il explore le roman du premier film de Back to the Future, une page à la fois. C'est une chose que je souhaite lire.

Cliquez pour lire.

Toutefois, Tumblr affiche ses publications dans l'ordre chronologique inverse, c'est-à-dire en commençant par les publications les plus récentes. Cela a du sens pour de nombreux sites sur Tumblr, mais dans ce cas, je veux vraiment les lire dans l'ordre dans lequel ils ont été écrits. La mise en page actuelle du site signifie que, pour ce faire, je dois faire défiler vers le haut le premier message (le premier écrit), faire défiler le texte au fur et à mesure que je le lis, puis faire défiler vers le haut le deuxième message et faire défiler vers le bas. à travers ça…

Il s'agit d'un minuscule, minuscule problème du premier monde - totalement trivial et presque embarrassant. Mais cela ne signifie pas que je ne veux pas le réparer.

À la fin de ce didacticiel, vous ferez en sorte que ce Tumblr, ou tout autre Tumblr de votre choix, affiche automatiquement ses articles dans l'ordre chronologique de la page..


Comment peut-on le faire?

Nous n'avons aucun contrôle sur la conception du site BtotheF; il ne nous propose aucune option, nous ne pouvons donc pas modifier l'ordre d'affichage des publications sur la page côté serveur..

Mais une fois que le code HTML est envoyé au navigateur, c'est le nôtre. Nous pouvons le manipuler comme bon nous semble. Et, bien sûr, le langage avec lequel nous pouvons faire cela est JavaScript.

Je vais faire une démo rapide. J'utiliserai Chrome et je vous le recommande également. Si vous ne pouvez pas ou ne voulez pas, prenez une copie de Firebug..

Accédez à http://btothef.tumblr.com/ et ouvrez la console JavaScript (Outils> Console JavaScript, dans Chrome). Type:

 alerte ("Hi");

… Et appuyez sur Entrée.

Wow!… D'accord, d'accord, cela n'a pas prouvé grand chose. Essaye ça:

 document.body.appendChild (document.createTextNode ("Hi"));

Cela prendra le document HTML élément, puis ajoutez un nouveau nœud de texte (un morceau de texte, en gros) contenant le mot "Hi". Si vous n'avez pas suivi cela, familiarisez-vous avec HTML.

Pour voir le résultat, faites défiler vers le bas du Tumblr:

Un peu plus impressionnant, puisque nous avons en fait changé le contenu de la page. Le nouveau nœud de texte est juste en bas parce que nous avons utilisé appendChild () - qui ajoute le noeud spécifié après tout le reste à l'intérieur du . En ce qui concerne notre navigateur, les dernières lignes de HTML ressemblent maintenant à ceci:

  salut  

Alors! Maintenant nous avons deux problèmes:

  1. Comment utilisons-nous JavaScript pour réorganiser tous les articles de la page?
  2. Comment pouvons-nous y arriver automatiquement, sans avoir à jouer dans la console à chaque fois que nous lisons le Tumblr?

Nous allons aborder ces dans l'ordre.


Réarranger les poteaux

Tout d'abord, essayons de trouver comment "trouver" tous les articles dans le code HTML. Dans Chrome, cliquez avec le bouton droit de la souris sur le post supérieur et sélectionnez "Élément à inspecter". (Firebug devrait ajouter le même raccourci vers Firefox; pour les autres navigateurs, essayez l'icône en forme de loupe.)

L'onglet Éléments des outils de développement apparaît, l'élément sélectionné est mis en surbrillance:

Lorsque vous survolez différents éléments de cette vue HTML, vous les verrez mis en surbrillance dans la page elle-même. Finalement, vous constaterez que le message entier est contenu dans un div avec une classe de poster. Comme vous pouvez le voir sur la capture d'écran ci-dessus, il en existe plusieurs autres. div éléments, et ils sont tous contenus dans un maître div avec un id de Contenu.

Nous pouvons sélectionner tous ces éléments de publication à la fois avec une seule ligne de code; tapez ceci dans la console JavaScript:

 document.getElementById ("contenu"). getElementsByClassName ("post");

(Techniquement, nous aurions pu écrire document.getElementsByClassName ("post"), mais qui s'en soucie?)

Vous verrez - à nouveau dans Chrome - des commentaires:

Génial! Cela indique que cela a fonctionné. Si vous cliquez sur les flèches, vous verrez le contenu de chaque div.

Nous pourrions aussi bien assigner ceci à une variable, pour éviter de devoir le taper encore et encore:

 var posts = document.getElementById ("contenu"). getElementsByClassName ("post");

(Cette fois, la console reviendra indéfini; vous pouvez vérifier qu'il a correctement affecté la variable en tapant simplement le mot des postes dans la console.)

Nous pouvons parcourir tous les éléments de des postes comme s'il s'agissait d'un tableau:

 pour (var i = 0; i < posts.length; i++)  console.log(posts[i]); 

Appuyez sur Maj-Entrée pour ajouter une nouvelle ligne à votre code sans l'exécuter, dans la console JavaScript.. console.log () trace simplement son contenu sur la console, ce qui est beaucoup moins gênant qu’un alerte() et beaucoup moins perturbant que d'ajouter du texte au HTML DOM.

Le résultat de cette simple boucle sera simplement une liste de tous les div éléments. Cool. Donc, vraisemblablement, nous pouvons faire quelque chose comme ça…

 var numPosts = posts.length; pour (var i = numPosts - 1; i> = 0; i--) posts.push (posts [i]); 

Essaye le! Vous verrez ceci:

 TypeError: Object # n'a pas de méthode 'push'

Les rats.

Une liste de noeuds n'est pas un tableau

Quand on utilise getElementsByClassName (), nous ne récupérons pas un simple tableau d'éléments, nous récupérons une liste de noeuds. Comme un tableau, il s'agit d'une collection d'éléments. contrairement à un tableau, la collection est mise à jour en temps réel. Si le DOM HTML est modifié, le contenu de des postes obtient modifié pour correspondre.

Par exemple, créons une nouvelle div avec une classe de poster et l'ajouter à la Contenu div:

 var newPostDiv = document.createElement ("div"); newPostDiv.setAttribute ("classe", "post"); document.getElementById ("contenu"). appendChild (newPostDiv);

Exécutez cela, puis tapez des postes et appuyez sur Entrée. Vous verrez un extra div dans la liste - même si nous n'avons pas touché le des postes variable.

Depuis un NodeList n'est pas un tableau, il n'a pas la plupart des méthodes et propriétés de Tableau, tel que pousser() En fait, nous avons déjà utilisé la seule propriété: longueur. La seule méthode est .élément (n), qui obtient juste le ne élément de la liste.

Cependant, notre précédente démonstration avec appendChild () suggère une solution alternative: que se passerait-il si, au lieu d’essayer de réorganiser les éléments du NodeList dans le NodeList, nous les avons réorganisés dans la page?

Tout d’abord, nous allons parcourir la liste dans l’ordre inverse, et ajouter chaque élément à tour de rôle. Contenu div; ensuite, nous allons supprimer les messages d'origine.

Actualisez la page Tumblr pour éliminer tous les déchets supplémentaires que nous avons ajoutés au DOM, puis effectuez la première étape consistant à ajouter les éléments dans l'ordre inverse:

 // devons définir à nouveau les publications, car nous l'avons perdu lors de l'actualisation de var posts = document.getElementById ("contenu"). getElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Ok, maintenant nous… attendons, quoi?

Le premier message (chronologique) est déjà en haut et le dernier post en bas, aucun message ne se répète. Cela peut paraître surprenant, mais cela a du sens: nous n'avons pas cloner des éléments du NodeList, nous venons de les annexer au Contenu div, dans l'ordre inverse. Depuis le NodeList reflète toujours le contenu du HTML DOM, nous venons de déplacé chacun des 11 éléments à une nouvelle position - le 11ème élément a été ajouté à la fin (pas de changement de position); alors le 10 a été déplacé pour être après cela; le 9 après cela, et ainsi de suite, jusqu'à ce que le 1er élément soit juste à la fin.

Donc, le problème est résolu, en cinq lignes simples de code. Maintenant automatisons-le.


Le transformer en une extension de navigateur

Trois des quatre principaux navigateurs vous permettent de créer des extensions de navigateur - des modules complémentaires installables - à l'aide de JavaScript. (Vous ne serez pas surpris d'apprendre qu'Internet Explorer est une exception.) Voici les instructions pour Chrome, celles de Firefox et celles de Safari..

Mais nous n'utiliserons aucun de ceux-ci. Au lieu de cela, nous utiliserons un excellent complément appelé Greasemonkey, qui vous permettra d’installer de petits scripts JS sans avoir besoin de les empaqueter sous forme d’extensions de navigateur complètes. Essentiellement, il injecte des extraits de JavaScript dans la page, une fois celle-ci chargée..

Chrome dispose déjà du support Greasemonkey. Opera a quelque chose de très similaire à Greasemonkey: UserJS. Pour Firefox, vous devez installer l'extension Greasemonkey. Pour Safari, installez SIMBL, puis GreaseKit. Pour IE, installez IE7Pro ou Trixie.

Écrire le script Greasemonkey

Créez un nouveau fichier texte et nommez-le. ChronologicalTumblr.user.js. Assurez-vous de supprimer la valeur par défaut .SMS extension, et que vous utilisez .user.js, plutôt que juste .js - c'est l'extension d'un script Greasemonkey.

Copiez notre code de réarrangement dans le fichier:

 var posts = document.getElementById ("contenu"). getElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Maintenant, nous devons ajouter des métadonnées supplémentaires en haut du script - des détails sur le script lui-même. Tous ces détails doivent être commentés, en commençant par == UserScript == et se terminant par == / UserScript ==:

 // == UserScript == // // == / UserScript == var posts = document.getElementById ("contenu"). GetElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Tout d'abord, nous allons ajouter un nom et une description:

 // == UserScript == // @name Chronological Tumblr // @description Affiche les publications de Tumblr par ordre chronologique // == / UserScript == var posts = document.getElementById ("contenu"). GetElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Ensuite, nous spécifierons un espace de noms. La combinaison du nom et de l’espace de noms est ce qui identifie de manière unique le script; si vous essayez d'installer un autre script Greasemonkey avec le même nom et comme un script existant, il écrasera l’ancien - si seulement le nom ou la correspondance d'espace de noms, il ne vous reste plus qu'à installer le nouveau à côté de l'ancien.

Il est courant d'utiliser une URL ici, donc j'utiliserai Activetuts +. Vous devriez utiliser le vôtre, puisque vous en avez le contrôle:

 // == UserScript == // @name Chronological Tumblr // @description Affiche les publications de Tumblr par ordre chronologique // @namespace http://active.tutsplus.com/ // == / UserScript == var posts = document. getElementById ("contenu"). getElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Nous devons maintenant spécifier les URL que ce script doit affecter, c’est-à-dire sur les pages Web dans lesquelles le code JavaScript doit être automatiquement injecté. Je veux que ce script fonctionne sur la page d'accueil BtotheF, ainsi que sur les autres pages d'archives, comme http://btothef.tumblr.com/page/2:

 // == UserScript == // @name Chronological Tumblr // @description Affiche les publications de Tumblr par ordre chronologique // @namespace http://active.tutsplus.com/ // @include http://btothef.tumblr.com. / // @include http://btothef.tumblr.com/page/* // == / UserScript == var posts = document.getElementById ("contenu"). getElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

le * est un wildcard; il garantit que le script sera inséré dans chaque page d'archive du Tumblr de BtotheF.

Nous pourrions utiliser un caractère générique pour afficher chaque page d'archive de Tumblr dans l'ordre chronologique:

 // == UserScript == // @name Chronological Tumblr // @description Affiche les publications de Tumblr par ordre chronologique // @namespace http://active.tutsplus.com/ // @include http: //*.tumblr.com / // @include http: //*.tumblr.com/page/* // == / UserScript == var posts = document.getElementById ("contenus"). getElementsByClassName ("post"); var numPosts = posts.length; for (var i = numPosts - 1; i> = 0; i--) document.getElementById ("contenu"). appendChild (posts [i]); 

Dans ce cas, il peut être judicieux d'améliorer votre script pour insérer un bouton ou un lien dans la page qui réorganise les publications lorsque vous cliquez dessus. De cette façon, vous pouvez l’utiliser quand vous le souhaitez, sans avoir à ajouter manuellement chaque URL de Tumblr en tant que @comprendre paramètre.

Vous pouvez ajouter d'autres paramètres de métadonnées, mais c'est tout ce dont nous avons besoin pour l'instant..

Finition

L'installation du script dans Chrome est simple: il suffit de le glisser-déposer de votre disque dur dans une fenêtre du navigateur. Cela vous avertira que les scripts peuvent être dangereux (cliquez simplement sur Continuer), puis vérifiez à nouveau que vous souhaitez installer celui-ci:

Appuyez sur Installer. Si vous utilisez un autre navigateur, reportez-vous au manuel du script Greasemonkey correspondant. Dans tous les cas, ce sera simple..

Une fois installé, vous pouvez le voir dans votre liste d’extensions:

Retournez à http://btothef.tumblr.com/, ou cliquez sur Actualiser si vous l'avez toujours ouvert..

Les messages sont maintenant automatiquement affichés dans l'ordre chronologique!

Ce n’est pas parfait: vous avez peut-être remarqué que les boutons de navigation ont été déplacés en haut de la page, car ils sont contenus dans une div avec une classe de poster. Mais bon - si ça vous dérange, vous avez les outils pour le réparer maintenant.