J'ai récemment rencontré une fonction comme celle-ci lorsque je travaillais sur un projet : mettre en évidence des mots-clés dans des pages Web.
Je pensais que ce serait une opération simple qui pourrait être réalisée avec le remplacement innerHTML, mais j'ai rencontré de nombreux problèmes. Cet article enregistre ces problèmes et la solution parfaite finale, dans l'espoir d'être utile aux amis qui ont la même expérience. Si vous n'êtes intéressé que par les résultats, ignorez le processus et passez directement aux résultats ~
Pratique courante : remplacement régulierIdée : si vous souhaitez mettre en évidence des éléments, vous devez extraire les mots-clés et les envelopper dans des balises, puis ajuster le style des balises. Utilisez innerHTML ou outHTML, mais pas innerText ou outText.
const regex = new RegExp(keyword,g)element.innerHTML = element.innerHTML.replace(regex,<b class=a>+keyword+</b>)element.classList.add(highlight)
Les dangers cachés de cela sont les suivants :
()/div<div id=parent> <div class=test>test</div> </div>
L'élément de nœud parent mot-clé effectue un traitement de teinture d'arrière-plan via la classe, ce qui pollue le DOM d'origine dans une certaine mesure et peut affecter le repositionnement de l'élément. (En tant que plug-in, nous espérons modifier le moins possible le DOM d'origine)
Optimisation régulière : seuls les éléments de processus situés dans les balisesvar formatKeyword = text.replace(/[-////^$*+?.()|[/]{}]/g, '//$&') // Échappe les caractères spéciaux contenus dans le mot-clé, Par exemple, /.var finder = new RegExp(>.*?++.*?<) // Extrayez le texte situé dans la balise pour éviter une mauvaise utilisation de la classe, de l'identifiant, etc. element.innerHTML = element.innerHTML.replace(finder,function(matched){ return matched.replace(text,<br>+text+</br>)})//Remplacer les mots-clés dans le texte extrait dans la balise
Cela peut résoudre la plupart des problèmes, mais le problème qui existe toujours est que tant qu'il y a un symbole < similaire dans l'attribut de balise, les règles de correspondance seront rompues et le contenu d'extraction régulier sera erroné pour personnaliser n'importe quel contenu. ces caractères spéciaux sont donc inévitables.
<div dataset=p>d>Remplacer</div>Optimisation régulière 2 : effacer les balises susceptibles d'être affectées
<div id=keyword>keyword</div> =》Remplacer la balise fermante par une variable [replaced1]keyword[replaced2]//L'id=keyword dans la balise fermante ne sera pas traité=》[replaced1]<b>keyword </b >[replaced2] =》Remplacer la variable temporaire remplacée par la balise d'origine <div id=keyword><b>mot-clé</b></div>
Plus important encore, cette méthode ne peut pas extraire correctement la balise lorsque la valeur de la balise contient le symbole <>.
Bref, après de nombreuses tentatives, diverses situations n’ont pas été traitées efficacement par la régularisation. Ensuite, j'ai changé d'avis et je l'ai traité via des nœuds au lieu de chaînes. element.childNodes peut nettoyer plus efficacement les informations d'interférence dans les balises.
[Solution parfaite] Traitement via les nœuds DOM<div id=parent> mot-clé 1 <span id=child> mot-clé 2 </span> </div>
Obtenez tous les nœuds enfants via parent.childNodes. Le nœud enfant peut être remplacé par innerText.replce(keyword,result)
pour obtenir l'effet de surbrillance souhaité, comme suit : <span id=child><b>keyword</b> 2</span>
(Traitement récursif : lorsque l'enfant L'opération de remplacement est effectuée lorsque le nœud ne contient pas de nœuds enfants).
Cependant, le mot-clé 1 est un nœud de texte et ne peut modifier que le contenu du texte, ne peut pas ajouter de code HTML et ne peut pas contrôler son style indépendamment. Les nœuds de texte ne peuvent pas être convertis en nœuds ordinaires, ce qui est aussi la chose la plus pénible.
Enfin ~, voici l'objet de cet article Grâce à cette fonction, je suis entré en contact sérieux avec les nœuds de texte pour la première fois. À partir de là, j'ai découvert Text et utilisé la méthode consistant à couper les nœuds de texte et à les remplacer pour obtenir une mise en évidence.
Code source et points forts de la restauration, voir le code source
const reg = new RegExp(keyword.replace(/[-////^$*+?.()|[/]{}]/g, '//$&'))highlight = function (node,reg ){ if (node.nodeType == 3) { //Traiter uniquement les nœuds de texte const match = node.data.match(new RegExp(reg)); document.createElement(b); highlightEl.dataset.highlight=y const wordNode = node.splitText(match.index) wordNode.splitText(match[0].length); // Couper en trois nœuds de texte après le premier mot-clé et const wordNew = document.createTextNode(wordNode.data); highlightEl.appendChild(wordNew);//highlight Le nœud est construit avec succès wordNode.parentNode.replaceChild(highlightEl, wordNode); // Remplacer le nœud de texte} } else if (node.nodeType == 1 && node.dataset.highlight!=y ) { for (var i = 0 ; je < node.childNodes.length; i++) { highlight(node.childNodes[i], reg);Résumer
Ce qui précède est la solution parfaite pour mettre en évidence les mots-clés en HTML introduits par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Je tiens également à remercier tout le monde pour votre soutien au site d'arts martiaux VeVb !