Organisation einer Suche auf einer Webseite in JavaScript (ohne jQuery)

Vor ein paar Tagen erhielt ich von der Firma eine Testaufgabe für die freie Stelle Front-End-Entwickler. Natürlich bestand die Aufgabe aus mehreren Punkten. Aber jetzt konzentrieren wir uns nur auf eine davon - die Organisation der Suche auf der Seite. Das heißt, banale Suche nach dem in das Feld eingegebenen Text (analog zu Strg + F im Browser). Die Besonderheit der Aufgabe war, dass die Verwendung von JS-Frameworks oder -Bibliotheken verboten ist. Alle schreiben in nativem nativem JavaScript .

(Aus Gründen der Klarheit werde ich den gesamten Artikel weiterhin mit Screenshots und Code begleiten, damit Sie und ich verstehen, wovon ich in einem bestimmten Moment spreche.)

Eine Lösung finden


Erster Gedanke: Jemand hat genau das bereits geschrieben, Sie müssen googeln und kopieren und einfügen. Also habe ich es getan. In einer Stunde fand ich zwei gute Skripte, die im Wesentlichen auf die gleiche Weise funktionierten, aber unterschiedlich geschrieben waren. Ich habe den ausgewählt, dessen Code ich besser verstanden und in die Seite meines alten Mannes eingefügt habe.

Wenn jemand interessiert ist, habe ich den Code hier genommen .

Das Skript hat sofort funktioniert. Ich dachte, dass das Problem behoben war, aber wie sich herausstellte, war es kein Vergehen für den Autor des Skripts, dass es einen großen Fehler gab. Das Skript hat den gesamten Inhalt des Tags durchsucht ... und, wie Sie wahrscheinlich bereits vermutet haben, wird bei der Suche nach einer Kombination von Zeichen, die einem Tag oder seinen Attributen ähneln, die gesamte HTML-Seite unterbrochen.

Warum hat das Skript nicht richtig funktioniert?


Alles ist einfach. Das Skript funktioniert wie folgt. Zuerst schreiben wir den gesamten Inhalt des Body- Tags in eine Variable, suchen dann nach Übereinstimmungen mit dem regulären Ausdruck (der Benutzer legt ihn beim Eingeben in das Textfeld fest) und ersetzen dann alle Übereinstimmungen durch den folgenden Code:

 <span style="background-color: yellow;">... ...</span> 

Und dann ersetzen wir das aktuelle Body- Tag durch das neu erhaltene. Das Markup wird aktualisiert, die Stile ändern sich und alle gefundenen Ergebnisse werden auf dem Bildschirm gelb hervorgehoben.

Sie haben wahrscheinlich bereits verstanden, wo das Problem liegt, aber ich werde es dennoch genauer erläutern. Stellen Sie sich vor, Sie geben das Wort "div" in das Suchfeld ein. Wie Sie verstehen, gibt es im Körper viele andere Tags, einschließlich div . Und wenn wir alle die oben genannten Stile auf das „div“ anwenden, ist dies kein Block, aber es ist nicht klar, was, da das Design bricht. Als Ergebnis erhalten wir nach dem Überschreiben des Markups eine vollständig fehlerhafte Webseite. Es sieht so aus.

Es war vor der Suche: Fotos ins Internet hochladen Vollständig verblassen
Es wurde nach der Suche: Foto kostenlos hochladen Vollständig verblassen

Wie Sie sehen können, bricht die Seite vollständig. Kurz gesagt, das Skript erwies sich als nicht funktionsfähig, und ich beschloss, mein eigenes von Grund auf neu zu schreiben, worum es in diesem Artikel geht.

Also schreiben wir ein Skript von Grund auf neu


Wie alles für mich aussieht.



Jetzt interessiert uns das Suchformular. Er umkreiste sie mit einer roten Linie.

Lass uns ein bisschen schauen. Ich habe dies wie folgt implementiert (bisher reines HTML). Ein Formular mit drei Tags.

Der erste dient zur Eingabe von Text;
Die zweite - um die Suche abzubrechen (abwählen);
Der dritte dient zur Suche (markieren Sie die gefundenen Ergebnisse).

 <form> <input type="text" value="" placeholder="Search" autofocus> <input type="button" value=" " title=" "> <input type="submit" value=" " title=" "> </form> 

Wir haben also ein Eingabefeld und 2 Schaltflächen. Ich werde JavaScript in die js.js schreiben. Angenommen, Sie haben es bereits erstellt und verbunden.

Das erste, was wir tun werden: Registrieren Sie die Funktionsaufrufe, wenn Sie auf die Schaltfläche Suchen und Abbrechen klicken. Es wird so aussehen:

 <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> 

Lassen Sie uns ein wenig erklären, was hier ist und warum.

Wir geben das Textfeld id = "zu findender Text" ( diese ID bezieht sich auf das Element von js ).

Wir geben der Abbrechen- Schaltfläche die folgenden Attribute: type = "button" onclick = "javascript: FindOnPage ('text-to-find', false); return false; "

- Typ: Schaltfläche
- Wenn diese Taste gedrückt wird, wird die FindOnPage-Funktion aufgerufen ('text-to-find', false). und übergibt die ID des Feldes mit dem Text false

Wir geben der Suchschaltfläche die folgenden Attribute: type = "button" onclick = "javascript: FindOnPage ('text-to-find', true); return false; "

- Geben Sie Folgendes ein: Senden (keine Schaltfläche, da Sie hier nach Eingabe des Felds die Eingabetaste oder auch die Schaltfläche verwenden können)
- Wenn diese Taste gedrückt wird, wird die FindOnPage-Funktion aufgerufen ('text-to-find', true). und übergibt die ID des Feldes mit dem Text true

Sie haben wahrscheinlich noch ein Attribut bemerkt: wahr / falsch . Wir werden es verwenden, um zu bestimmen, welche Taste gedrückt wurde (Suche abbrechen oder Suche starten). Wenn wir auf Abbrechen klicken, übergeben Sie false . Wenn wir auf die Suche klicken, übergeben Sie true .

OK, mach weiter. Gehen Sie zu JavaScript

Wir gehen davon aus, dass Sie die js-Datei bereits erstellt und mit dem DOM verbunden haben.

Bevor wir mit dem Schreiben von Code beginnen, machen wir eine Pause und besprechen zunächst, wie alles funktionieren soll. Das heißt, Im Wesentlichen werden wir einen Aktionsplan erstellen. Daher müssen wir bei der Eingabe von Text in das Feld eine Suche auf der Seite durchführen, Tags und Attribute sollten jedoch nicht betroffen sein. Das heißt, Nur Textobjekte. Wie man das erreicht - ich bin sicher, es gibt viele Möglichkeiten. Aber jetzt werden wir reguläre Ausdrücke verwenden.

Der nächste reguläre Ausdruck sucht also nur nach der Textspur. Typ: "> ... Text ... <". Das heißt, Es werden nur Textobjekte durchsucht, während Tags und Attribute unberührt bleiben.

 />(.*?)</g 

So finden wir die erforderlichen Teile des Codes, die wir analysieren und nach Übereinstimmungen mit dem vom Benutzer eingegebenen Text suchen. Anschließend fügen wir den gefundenen Objekten Stile hinzu und ersetzen anschließend den HTML-Code durch einen neuen.

Fangen wir an. Erstens die Variablen, die wir brauchen.

 var input,search,pr,result,result_arr, locale_HTML, result_store; //input -  ,    //search -      //pr -     <body></body> //result -    pr (..    ) //result_arr -  pr,      //locale_HTML -  <body></body>    ,     

Und bestimmen Sie sofort den Wert locale_HTML , unabhängig davon, ob wir nach etwas suchen oder nicht. Dies ist erforderlich, um die Originalseite sofort zu speichern und die Stile zurücksetzen zu können.

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () 

Ok, jetzt lohnt es sich, eine Funktion zu erstellen, die vom DOM aufgerufen wird. Schätzen Sie sofort, dass wir im Inneren 2 Funktionen haben sollten, von denen jede abhängig von der gedrückten Taste funktioniert. Schließlich führen wir entweder eine Suche durch oder setzen sie auf Null. Und dies wird, wie Sie sich erinnern, durch das Attribut true / false gesteuert. Sie müssen auch verstehen, dass bei einer erneuten Suche die alten Stile zurückgesetzt werden müssen. Somit erhalten wir folgendes:

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Ok, ein Teil der Logik ist implementiert, mach weiter. Das empfangene Wort muss auf die Anzahl der Zeichen überprüft werden. Warum müssen wir schließlich nach 1 Buchstaben / Symbol suchen? Im Allgemeinen habe ich beschlossen, dies auf 3+ Zeichen zu beschränken.

Also nehmen wir zuerst den Wert, den der Benutzer eingegeben hat, und führen abhängig von seiner Länge entweder die Hauptsuchfunktion oder die Warn- und Nullstellungsfunktion aus. Es wird so aussehen:

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { //  } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Jetzt werde ich diesen Abschnitt des Codes erklären. Das einzige, was nicht klar sein konnte, ist diese Zeile:

Funktion FindOnPageBack () {document.body.innerHTML = locale_HTML; }}

Hier ist alles einfach: Die innerHTML- Methode gibt den HTML- Code des Objekts zurück. In diesem Fall ersetzen wir einfach den aktuellen Text durch den ursprünglichen, den wir beim Laden der gesamten Seite gespeichert haben.

Wir gehen weiter. Wir geben den Hauptvariablen Werte.

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { function FindOnPageGo() { search = '/'+input+'/g'; //     pr = document.body.innerHTML; //     body result = pr.match(/>(.*?)</g); //       result_arr = []; //       () } } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Zu diesem Zeitpunkt haben wir also bereits die wichtigsten Variablen und Werte. Jetzt müssen wir die erforderlichen Teile der Codestile mit einem hervorgehobenen Hintergrund angeben. Das heißt, Überprüfen des ausgewählten Textes auf einen regulären Ausdruck (tatsächlich wird der vom regulären Ausdruck ausgewählte Text erneut vom regulären Ausdruck analysiert) Dazu müssen Sie aus dem eingegebenen Text (erledigt) einen regulären Ausdruck erstellen und dann die als Takt übergebene Methode ausführen. Hier hilft uns die eval () -Methode.

Nachdem wir den Text ersetzt und das Ergebnis durch Stile erhalten haben, müssen wir im Allgemeinen das aktuelle HTML durch das empfangene ersetzen. Wir machen es

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { function FindOnPageGo() { search = '/'+input+'/g'; //     pr = document.body.innerHTML; //     body result = pr.match(/>(.*?)</g); //       result_arr = []; //       () for(var i=0; i<result.length;i++) { result_arr[i] = result[i].replace(eval(search), '<span style="background-color:yellow;">'+input+'</span>'); //  ,        } for(var i=0; i<result.length;i++) { pr=pr.replace(result[i],result_arr[i]) //    html       } document.body.innerHTML = pr; // html  } } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Im Wesentlichen ist alles fertig und das Skript funktioniert bereits. Aber fügen Sie ein paar weitere Details für die Schönheit hinzu.

1) Schneiden Sie die Leerzeichen im Text, den der Benutzer eingibt. Fügen Sie diesen Code ein:

  input = numer.replace(/^\s+/g,''); input = numer.replace(/[ ]{1,}/g,' '); 

Nach dieser Zeile:

  input = document.getElementById(name).value; //     html 

2) Wir werden nach Zufällen suchen (wenn keine Übereinstimmungen gefunden werden, werden wir darüber informieren). Dieser Code wird nach Variablen in die Funktion FindOnPageGo () eingefügt.

  var warning = true; for(var i=0;i<result.length;i++) { if(result[i].match(eval(search))!=null) { warning = false; } } if(warning == true) { alert('    '); } 

Sie können die Quelle hier sehen .
Sie können die Quelle hier herunterladen.

Nun alles. Natürlich können Sie dem ersten gefundenen Ergebnis eine Schriftrolle hinzufügen, eine Live-Ajax-Suche, und Sie können sich sogar endlos verbessern. Dies ist eine eher primitive Suche auf der Website. Der Zweck des Artikels war es, Anfängern zu helfen, wenn die gleiche Frage wie bei mir auftaucht. Immerhin habe ich keine einfache fertige Lösung gefunden.

PS: Für einen korrekten Betrieb ist es erforderlich, die Silbentrennung im HTML-Dokument an den Stellen zu entfernen, an denen sich zwischen den Tags Klartext befindet.

Zum Beispiel anstelle von

  <p>    </p> 

Muss
  <p>    </p> 

Dies ist nicht wichtig. Sie können diese Übertragungen automatisch im Dienst entfernen, aber Sie können mir gleichzeitig mitteilen, wie das Problem behoben werden soll, wenn Sie dies vor mir verstehen.

Wenn jemand dies geschrieben hat, aber bei einer Live-Suche die Quelle teilt, ist es interessant zu analysieren.

Ich freue mich über konstruktive Kritik, Meinungen, vielleicht Empfehlungen.

Kürzlich habe ich einen kleinen Code hinzugefügt und eine Live-Suche auf der Seite durchgeführt. Damit ist die Frage geklärt. HTML- Code hat sich nicht geändert. JS kann hier schauen.

Die Suche wird mit Tags der Klasse "place_for_live_search" durchgeführt. Damit der Algorithmus den gewünschten Inhalt analysiert, fügen Sie die Klasse hinzu und fertig.

Source: https://habr.com/ru/post/de438382/


All Articles