Il y a quelques jours, j'ai reçu une tâche de test de la société pour le dev Front-end vacant. Bien sûr, la tâche consistait en plusieurs points. Mais maintenant, nous allons nous concentrer uniquement sur l'un d'eux - l'organisation de la recherche sur la page. C'est-à-dire recherche banale par le texte saisi dans le champ (analogue de Ctrl + F dans le navigateur). La particularité de la mission était que l'utilisation de tout framework ou bibliothèque JS est interdite.
Tous écrivent en JavaScript natif natif .
(Par souci de clarté, je continuerai à accompagner l'intégralité de l'article de captures d'écran et de code, afin que vous et moi comprenions de quoi nous parlons à un moment donné)Trouver une solution
Première pensée: quelqu'un a déjà écrit exactement cela, vous devez google et copier-coller. Alors je l'ai fait. En une heure, j'ai trouvé deux bons scripts qui fonctionnaient essentiellement de la même manière, mais qui étaient écrits différemment. J'ai choisi celui dont j'ai mieux compris le code et inséré dans la page de mon vieil homme.
Si quelqu'un est intéressé, j'ai pris le code ici .Le script a immédiatement fonctionné. Je pensais que le problème était résolu, mais il s'est avéré que cela n'offensait pas l'auteur du script, il y avait un énorme défaut. Le script a recherché tout le contenu de la balise
...
et, comme vous l'avez probablement déjà deviné, lorsque vous recherchez une combinaison de caractères qui ressemblent à une balise ou à ses attributs, la page HTML entière se rompt.
Pourquoi le script ne fonctionnait-il pas correctement?
Tout est simple. Le script fonctionne comme suit. Tout d'abord, nous écrivons le contenu entier de la balise
body dans une variable, puis recherchons des correspondances avec l'expression régulière (l'utilisateur la définit lors de la saisie dans le champ de texte), puis nous remplaçons toutes les correspondances par le code suivant:
<span style="background-color: yellow;">... ...</span>
Et puis nous remplaçons la balise
body actuelle par la nouvelle reçue. Le balisage est mis à jour, les styles changent et tous les résultats trouvés sont surlignés en jaune à l'écran.
Vous avez probablement déjà compris quel est le problème, mais je vais néanmoins vous expliquer plus en détail. Imaginez entrer le mot
«div» dans la boîte de recherche. Comme vous le comprenez, à l'intérieur du
corps, il existe de nombreuses autres balises, y compris
div . Et si nous appliquons tous les styles mentionnés ci-dessus à la
"div" , alors ce ne sera pas un bloc, mais ce n'est pas clair, car le design se casse. Par conséquent, après avoir remplacé le balisage, nous obtenons une page Web complètement cassée. Cela ressemble à ceci.
C'était avant la recherche:
Se fanent complètementC'est devenu après la recherche:
Se fanent complètementComme vous pouvez le voir, la page se casse complètement. En bref, le script s'est avéré inopérant, et j'ai décidé d'écrire le mien à partir de zéro, c'est de cela que traite cet article.
Nous écrivons donc un script à partir de zéro
Comment tout me semble.

Maintenant, nous sommes intéressés par le formulaire de recherche. Il l'a encerclée avec une ligne rouge.
Regardons un peu. J'ai implémenté cela comme suit (jusqu'à présent en HTML pur). Un formulaire avec trois balises.
Le premier sert à saisir du texte;
Le second - pour annuler la recherche (désélectionner);
Le troisième est pour la recherche (mettez en surbrillance les résultats trouvés).
<form> <input type="text" value="" placeholder="Search" autofocus> <input type="button" value=" " title=" "> <input type="submit" value=" " title=" "> </form>
Nous avons donc un champ de saisie et 2 boutons. J'écrirai JavaScript dans le js.js. Supposons que vous l'ayez déjà créé et connecté.
La première chose que nous allons faire: enregistrer les appels de fonction en cliquant sur le bouton de recherche et le bouton d'annulation. Cela ressemblera à ceci:
<form> <input class="place_for_search" type="text" id="text-to-find" value="" placeholder="Search" autofocus> <input class="button_for_turn_back" type="button" onclick="javascript: FindOnPage('text-to-find',false); return false;" value=" " title=" "> <input class="button_for_search" type="submit" onclick="javascript: FindOnPage('text-to-find',true); return false;" value=" " title=" "> </form>
Expliquons un peu ce qui se trouve ici et pourquoi.
Nous donnons le champ de texte
id = "text-to-find" (
cet id fera référence à l'élément de js ).
Nous donnons au
bouton d' annulation
les attributs suivants:
type = "bouton" onclick = "javascript: FindOnPage ('text-to-find', false); return false; "-
Type: bouton-
Lorsqu'elle est pressée, la fonction FindOnPage est appelée ('text-to-find', false); et passe l'id du champ avec le texte, falseNous donnons au
bouton de recherche
les attributs suivants:
type = "button" onclick = "javascript: FindOnPage ('text-to-find', true); return false; "-
Tapez: soumettre (pas un bouton car ici vous pouvez utiliser Entrée après avoir entré le champ, ou vous pouvez également utiliser le bouton)-
Lorsqu'elle est pressée, la fonction FindOnPage est appelée ('text-to-find', true); et passe l'id du champ avec le texte, trueVous avez probablement remarqué un autre attribut:
vrai / faux . Nous l'utiliserons pour déterminer le bouton sur lequel vous avez appuyé (annuler la recherche ou lancer la recherche). Si nous cliquons sur annuler, puis passons
faux . Si nous cliquons sur la recherche, passons
vrai .
OK, continue. Accéder à JavaScript
Nous supposons que vous avez déjà créé et connecté le fichier js au DOM.
Avant de commencer à écrire du code, prenons une pause et discutons d'abord comment tout devrait fonctionner. C'est-à-dire essentiellement, nous rédigerons un plan d’action. Ainsi, nous avons besoin que lors de la saisie de texte dans le champ, une recherche soit effectuée sur la page, mais les balises et les attributs ne devraient pas être affectés. C'est-à-dire objets texte uniquement. Comment y parvenir - je suis sûr qu'il existe de nombreuses façons. Mais maintenant, nous allons utiliser des expressions régulières.
Ainsi, la prochaine expression régulière ne recherchera que la trace de texte. tapez: "> ... texte ... <". C'est-à-dire seuls les objets texte seront recherchés, tandis que les balises et les attributs resteront intacts.
/>(.*?)</g
Nous allons donc trouver les parties nécessaires du code que nous analyserons et rechercherons des correspondances avec le texte que l'utilisateur a entré. Ensuite, nous ajouterons des styles aux objets trouvés et remplacerons ensuite le code html par un nouveau.
Commençons. Tout d'abord, les variables dont nous avons besoin.
var input,search,pr,result,result_arr, locale_HTML, result_store;
Et déterminez immédiatement la valeur locale_HTML , que nous recherchions ou non quelque chose. Cela est nécessaire pour enregistrer immédiatement la page d'origine et avoir la possibilité de réinitialiser les styles.
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Ok, maintenant ça vaut la peine de créer une fonction qui est appelée depuis le DOM . Estimez immédiatement qu'à l'intérieur, nous devrions avoir 2 fonctions, chacune fonctionnant selon le bouton enfoncé. Après tout, nous effectuons une recherche ou la mettons à zéro. Et cela est contrôlé par l'attribut true / false , comme vous vous en souvenez. Vous devez également comprendre que lorsque vous effectuez une nouvelle recherche, les anciens styles doivent être réinitialisés. Ainsi, nous obtenons ce qui suit:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Ok, une partie de la logique est implémentée, passez à autre chose. Il est nécessaire de vérifier le mot reçu pour le nombre de caractères. Après tout, pourquoi devons-nous rechercher 1 lettre / symbole. En général, j'ai décidé de limiter cela à 3+ caractères.
Ainsi, nous prenons d'abord la valeur entrée par l'utilisateur et, selon sa longueur, nous effectuons soit la fonction de recherche principale, soit la fonction d'avertissement et de mise à zéro. Cela ressemblera à ceci:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Je vais maintenant expliquer cette section du code. La seule chose qui ne pouvait pas être claire est cette ligne:
function FindOnPageBack () {document.body.innerHTML = locale_HTML; }
Tout est simple ici: la méthode innerHTML renvoie le code html de l'objet. Dans ce cas, nous remplaçons simplement le corps actuel par celui d'origine que nous avons enregistré lors du chargement de la page entière.
Nous continuons. Nous donnons des valeurs aux principales variables.
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Donc, à ce stade, nous avons déjà les principales variables et valeurs. Maintenant, nous devons donner les parties nécessaires des styles de code avec un arrière-plan en surbrillance. C'est-à-dire vérifier le texte sélectionné pour une expression régulière (en fait, le texte sélectionné par l'expression régulière est à nouveau analysé par l'expression régulière). Pour ce faire, vous devez créer une expression régulière à partir du texte saisi (terminé), puis exécuter la méthode passée comme tact. Ici, la méthode eval () nous aidera.
En général, après avoir remplacé le texte et obtenu le résultat avec des styles, nous devons remplacer le html actuel par celui reçu. Nous le faisons.
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Essentiellement, tout est prêt et le script fonctionne déjà. Mais ajoutez quelques détails supplémentaires pour la beauté.
1) Coupez les espaces dans le texte que l'utilisateur entre. Insérez ce code:
input = numer.replace(/^\s+/g,''); input = numer.replace(/[ ]{1,}/g,' ');
Après cette ligne:
input = document.getElementById(name).value;
2) Nous vérifierons les coïncidences (si aucune correspondance n'est trouvée, nous en informerons). Ce code est inséré dans la fonction FindOnPageGo () après les variables.
var warning = true; for(var i=0;i<result.length;i++) { if(result[i].match(eval(search))!=null) { warning = false; } } if(warning == true) { alert(' '); }
Vous pouvez voir la source ici .
Vous pouvez télécharger la source ici .
Maintenant tout. Bien sûr, vous pouvez ajouter un défilement au premier résultat trouvé, une recherche ajax en direct, et en effet vous pouvez vous améliorer sans cesse. Maintenant, c'est une recherche plutôt primitive sur le site. Le but de l'article était d'aider les débutants si la même question se pose que la mienne. Après tout, je n'ai pas trouvé de solution toute faite et simple.
PS: pour un fonctionnement correct, il est nécessaire de supprimer la césure du texte dans le document html aux endroits où il y a du texte brut entre les balises.
Par exemple, au lieu de
<p> </p>
Doit
<p> </p>
Ce n'est pas important, vous pouvez vous débarrasser automatiquement de ces transferts sur le service, mais vous pouvez me dire en même temps comment y remédier, si vous comprenez avant moi.
De plus, si quelqu'un a écrit cela, mais avec une recherche en direct, partagez la source, il sera intéressant d'analyser.
Je serai heureux d'entendre des critiques constructives, des opinions, peut-être des recommandations.
Récemment, j'ai ajouté un petit code, fait une recherche en direct sur la page. Alors que la question est résolue. Le code HTML n'a pas changé. JS peut regarder ici .
La recherche est effectuée à l'aide de balises de classe "place_for_live_search". Donc, pour que l'algorithme analyse le contenu souhaité, ajoutez la classe et vous avez terminé.