Pleins feux sur jQuery replaceText

Toutes les deux semaines, nous examinerons de manière ultra ciblée un effet intéressant et utile, un plugin, un hack, une bibliothèque ou même une technologie astucieuse. Nous tenterons ensuite de déconstruire le code ou de créer un petit projet amusant avec celui-ci..

Aujourd'hui, nous allons jeter un coup d'œil à l'excellent plug-in replaceText jQuery. Intéressé? Commençons après le saut.


Un mot de l'auteur

En tant que développeurs Web, nous avons accès à une quantité stupéfiante de code prédéfini, qu’il s’agisse d’un petit extrait de code ou d’un framework à part entière. À moins que vous ne fassiez quelque chose d'incroyablement précis, les chances sont, il y a déjà quelque chose de pré-construit pour que vous puissiez tirer parti. Malheureusement, beaucoup de ces offres stellaires languissent dans l'anonymat, spécialement à la foule non-hardcore.

Cette série cherche à rectifier ce problème en introduisant du code utile, extrêmement bien écrit - qu’il s’agisse d’un plugin, d’un effet ou d’une technologie pour le lecteur. De plus, s'il est suffisamment petit, nous tenterons de déconstruire le code et de comprendre comment il le fait vaudou. S'il est beaucoup plus volumineux, nous allons essayer de créer un mini-projet avec celui-ci pour apprendre les ficelles du métier et, espérons-le, comprendre comment en faire usage dans le monde réel..


Présentation de replaceText

Nous démarrons en nous concentrant sur l'excellent plug-in replaceText de Ben Alman. Voici quelques infos rapides:

  • Type: Brancher
  • La technologie: JavaScript [Construit sur la bibliothèque jQuery]
  • Auteur: Ben Alman
  • Une fonction: Manière concise et discrète de remplacer le contenu textuel

Le problème

Remplacer le contenu de votre page semble extrêmement simple. Après tout, la méthode JavaScript native remplacer semble faire la même chose. Si vous vous sentez particulièrement paresseux, jQuery facilite également le remplacement de l'intégralité du contenu du conteneur..

 // En utilisant simplement remplacer $ ("# conteneur"). Text (). Replace (/ text / g, 'texte de remplacement') // Remplacement du contenu * entier * du conteneur var lazyFool = "contenu entier avec du texte remplacé en externe "; $ ("# conteneur"). html (lazyFool);

Comme dit le proverbe, ce n’est pas parce que vous pouvez le faire que vous devriez le faire. Ces deux méthodes sont généralement boudées [en dehors des cas extrêmes] car elles cassent un tas de choses en faisant ce qu'elles font.

Le problème principal de ces approches est qu’elles aplatissent la structure du DOM en vissant efficacement tous les nœuds non textuels contenus dans le conteneur. Si vous parvenez à remplacer le code HTML lui-même, utilisez innerHTML ou jQuery's html, vous décrochez toujours tous les gestionnaires d’événements attachés à l’un de leurs enfants, ce qui est un véritable casse-tête. C’est le principal problème que ce plugin cherche à résoudre.


La solution

La meilleure façon de gérer la situation et la manière dont le plugin la gère est de travailler avec et de modifier les nœuds de texte exclusivement..

Les nœuds de texte apparaissent dans le DOM, tout comme les nœuds ordinaires, à la différence qu’ils ne peuvent pas contenir d’enfants. Le texte qu'ils détiennent peut être obtenu en utilisant soit nodeValue ou Les données propriété.

En travaillant avec des nœuds de texte, nous pouvons simplifier considérablement la complexité du processus. Nous devons essentiellement parcourir les nœuds, vérifier s'il s'agit d'un nœud de texte et, dans l'affirmative, procéder à une manipulation intelligente afin d'éviter les problèmes..

Nous allons examiner le code source du plugin lui-même afin que vous puissiez comprendre comment le plugin implémente ce concept en détail.


Usage

Comme la plupart des plugins jQuery bien écrits, il est extrêmement facile à utiliser. Il utilise la syntaxe suivante:

$ (conteneur) .replaceText (texte, remplacement);

Par exemple, si vous devez remplacer toutes les occurrences du mot 'val' par 'valeur', par exemple, vous devrez instancier le plugin de la manière suivante:

 $ ("# conteneur"). replaceText ("val", "valeur");

Oui, c'est aussi simple que cela. Le plugin s'occupe de tout pour vous.

Si vous êtes du genre à utiliser des expressions régulières, vous pouvez le faire aussi!

 $ ("# conteneur"). replaceText (/ (val) / gi, "valeur");

Ne vous inquiétez pas du remplacement de contenu dans les attributs d'un élément, le plugin est assez intelligent..


Déconstruire la source

Étant donné que le plug-in est constitué de seulement 25 lignes de code, une fois dépouillés des commentaires, nous allons parcourir rapidement le code source en expliquant quel extrait fait quoi et dans quel but..

Voici la source, pour votre référence. Nous allons passer en revue chaque partie en détail ci-dessous.

 $ .fn.replaceText = function (recherche, remplace, text_only) retour this.each (fonction () var noeud = this.firstChild, val, new_val, remove = []; if (noeud) do if (noeud .nodeType === 3) val = node.nodeValue; new_val = val.replace (rechercher, remplacer); if (new_val! == val) if (! text_only && / 

Bon, passons à un niveau de code assez élevé..

 $ .fn.replaceText = function (rechercher, remplacer, text_only) ;

Étape 1 - Le wrapper générique pour un plugin jQuery. L’auteur s’est, à juste titre, abstenu d’ajouter des options insipides, les fonctionnalités fournies étant suffisamment simples pour en justifier une. Les paramètres doivent être explicites -- texte seulement sera traité un peu plus tard.

 retourne this.each (function () );

Étape 2 - this.each s'assure que le plugin se comporte lorsque le plugin est passé dans une collection d'éléments.

 var node = this.firstChild, val, new_val, remove = [];

Étape 3 - Déclaration requise des variables que nous allons utiliser.

  • nœud contient le premier élément enfant du noeud.
  • val détient la valeur actuelle du nœud.
  • new_val contient la valeur mise à jour du noeud.
  • retirer est un tableau qui contiendra un noeud qui devra être retiré du DOM. Je vais entrer dans les détails à ce sujet dans un peu.
 si (noeud) 

Étape 4 - Nous vérifions si le nœud existe réellement, c'est-à-dire que le conteneur qui a été transmis contient des éléments enfants. Rappelez-vous que nœud contient le premier élément enfant de l'élément passé.

 do  while (node ​​= node.nextSibling);

Étape 5 - La boucle essentiellement, bon, traverse les nœuds enfants en se terminant lorsque la boucle est au nœud final.

 if (node.nodeType === 3) 

Étape 6 - C'est la partie intéressante. Nous accédons au nodeType propriété [en lecture seule] du nœud pour en déduire le type de nœud. Une valeur de 3 implique qu'il s'agit d'un nœud de texte. Nous pouvons donc continuer. Si cela vous simplifie la vie, vous pouvez le réécrire comme suit: if (node.nodeType == Node.TEXT_NODE) ​​.

 val = node.nodeValue; new_val = val.replace (recherche, remplace);

Étape 7 - Nous stockons la valeur actuelle du nœud de texte, en premier lieu. Ensuite, nous remplaçons rapidement les occurrences du mot clé par le remplacement par le natif. remplacer Méthode JavaScript. Les résultats sont stockés dans la variable new_val.

 if (new_val! == val) 

Étape 8 - Procéder uniquement si la valeur a changé!

 si (! text_only && / 

Étape 9a - Se souvenir du texte seulement paramètre. Cela entre en jeu ici. Ceci est utilisé pour spécifier si le conteneur doit être traité comme un conteneur contenant des nœuds d'élément à l'intérieur. Le code effectue également une vérification interne rapide pour voir s'il contient du contenu HTML. Il le fait en recherchant une balise d'ouverture dans le contenu de new_val.

Si oui, un textnode est inséré avant le nœud actuel et le nœud actuel est ajouté au retirer tableau à traiter plus tard.

 else node.nodeValue = new_val; 

Étape 9b - S'il ne s'agit que de texte, injectez directement le nouveau texte dans le nœud sans passer par le jonglage DOM..

 remove.length && $ (remove) .remove ();

Étape 10 - Enfin, une fois la boucle exécutée, nous supprimons rapidement les nœuds accumulés du DOM. La raison pour laquelle nous le faisons une fois la boucle exécutée est que la suppression d'un nœud à mi-parcours videra la boucle elle-même..


Projet

Le petit projet que nous allons construire aujourd'hui est assez basique. Voici la liste de nos besoins:

  • Exigence primaire: Appliquer un effet de surbrillance au texte extrait de la saisie de l'utilisateur. Cela devrait être pris en charge complètement par le plugin.
  • Exigence secondaire: Suppression de la surbrillance à la volée, selon les besoins. Nous allons créer un petit extrait de code pour vous aider. Pas prêt pour la production mais devrait très bien fonctionner pour nos besoins.

Remarque: C’est plus une preuve de concept que quelque chose que vous pouvez simplement déployer sans être touché. Évidemment, afin d’empêcher que l’article devienne trop lourd, j’ai sauté un certain nombre de sections qui sont de la plus haute importance pour le code prêt à la production - la validation par exemple..

L’accent devrait être mis sur le plugin lui-même et les techniques de développement qu’il contient. Rappelez-vous qu’il s’agit plus d’une démo bêta pour montrer quelque chose de sympa qui peut être fait avec ce plugin. Toujours désinfecter et valider vos entrées!


La fondation: HTML et CSS

    Déconstruction: jQuery replaceText    

Déconstruction: jQuery replaceText

par Siddharth pour les adorables gens de Nettuts+

Cette page utilise le populaire plugin replaceText de Ben Alman. Dans cette démo, nous l'utilisons pour mettre en évidence des morceaux de texte arbitraires sur cette page. Remplissez le mot, vous êtes à la recherche et cliquez sur Go.

Appliquer la surbrillanceSupprimer

<-- Assorted text here -->

Le HTML devrait être assez explicatif. Tout ce que j'ai fait est de créer une entrée de texte, deux liens pour appliquer et supprimer la surbrillance, ainsi qu'un paragraphe contenant du texte assorti.

 body font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans serif; taille de police: 16px;  p marge: 20px 0 40px 0;  h1 font-size: 36px; rembourrage: 0; marge: 7px 0;  h2 font-size: 24px;  #container width: 900px; marge gauche: auto; marge droite: auto; remplissage: 50px 0 0 0; position: relative;  #haiz padding: 20px; arrière-plan: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; bordure: solide 1px # C9C9C9;  #search width: 600px; marge: auto 40px; text-align: center;  #keyword width: 150px; hauteur: 30px; rembourrage: 0 10px; bordure: solide 1px # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; arrière-plan: # F0F0F0; taille de police: 18px;  # apply-highlight, # remove-highlight padding-left: 40px;  .highlight background-color: yellow; 

Encore une fois, assez explicite et assez basique. La seule chose à noter est la classe appelée surligner que je définis. Cela sera appliqué au texte que nous devrons mettre en évidence.

A ce stade, votre page devrait ressembler à ceci:


L'interaction: JavaScript

Le premier ordre du jour consiste à établir rapidement un lien avec nos gestionnaires afin que le texte soit mis en surbrillance et non mis en évidence de manière appropriée..

 var searchInput = $ ("# mot-clé"), searchTerm, searchRegex; $ ("# apply-highlight"). click (highLight); $ ("# remove-highlight"). bind ("cliquez sur", fonction () $ ("# haiz"). removeHighlight (););

Devrait être assez simple. Je déclare quelques variables pour une utilisation ultérieure et attache les liens à leurs gestionnaires. surligner et enleverHighlight sont des fonctions extrêmement simples, nous allons regarder ci-dessous.

 fonction highLight () searchTerm = searchInput.val (); searchRegex = new RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ searchTerm +''); 
  • J'ai choisi de créer une fonction vanille, et non un plugin jQuery, car je suis paresseux comme un tas de pierres. Nous commençons par capturer la valeur de la zone de saisie.
  • Ensuite, nous créons un objet d'expression régulière en utilisant le mot clé de recherche.
  • Enfin, nous invoquons le replaceText plugin en passant les valeurs appropriées. Je choisis d'inclure directement terme de recherche dans le balisage par souci de concision.
 jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). each (function () ) avec (this.parentNode) replaceChild (this.firstChild, this););

Une méthode rapide et sale, hacky pour faire le travail. Et oui, c’est un plugin jQuery puisque je voulais me racheter. La classe est toujours codée en dur.

Je cherche simplement chaque balise span avec une classe de surligner et en remplaçant le noeud entier par la valeur qu'il contient.

Avant de préparer vos fourches, rappelez-vous qu’il s’agit uniquement de démonstration. Pour votre propre application, vous aurez besoin d’une méthode beaucoup plus sophistiquée de non mise en évidence..


Emballer

Et nous avons fini. Nous avons jeté un coup d'œil à un plugin incroyablement utile, parcouru le code source et avons finalement créé un mini-projet.