JavaScript: Bibliothek - Find Text
Ich möchte hier unsere bib.js um folgende Funktion erweitern:
findTxt()
Diese soll das übergeordnete Element bzw. Elemente eines Such-Strings ermitteln und zurückgeben.
Ausgangsposition der Suche ist ein Start-Element wie z.B.: document.body
oder die ID eines übergeordneten Elements: #start-id
(dieses sollte eindeutig sein ansonsten wird das erstgefundene Element durchsucht).
Von hierab wird in einer Rekursion abwärts nach dem gesuchten Begriff/Wort gesucht und bei einem Treffer
das Eltern-Element zurückgegeben.
Diese Funktion erwartet 2 Parameter findTxt( root , text ):
- root: übernimmt die Ausgangsposition der Suche:
- text: übernimmt den zu findenden Suchbegriff
... <div id="wrapper"> Das ist ein Beispieltext <div id="ebene-1" class="cl-ebene-1"> dem Du <span id="span-eins" class="sp-eins">bitte keine</span> Beachtung <p id="p-1">schenken solltest.</p> <div id="ebene-2"> Aber in diesem Beispieltext <span id="span-zwei" class="new-class">kannst Du auch</span> den Text finden. </div> </div> </div> ...
Suchen wir z.B. das Wort: Beispieltext oder Du, sollten wir zwei Treffer erhalten.
Um das zu erreichen sehen wir uns ersteinmal die Rekursion in unserer Funktion genauer an.
function findTxt( root , text ){ ... // Rekursion starten const walker = document.createTreeWalker( root, // Start der Suche (Node) NodeFilter.SHOW_TEXT, // durchsucht Text-Knoten null, // Platzhalter für zusätzliche Filterregeln false ); ... }
Da wir ja mehr als nur einen Treffer erzielen können müssen wir dafür sorge tragen, dass wir den/die Treffer
in einem Array speichern: const results = []
Die Methode document.createTreeWalker(...) startet die Rekursion.
Sie erwartet folgende Parameter:
- root,
- whatToShow,
- filter
Jetzt können wir unser Funktion erweitern:
function findTxt( root , text ){ const results = []; // Array für Treffer // Rekursion starten const walker = document.createTreeWalker( root, // Start der Suche (Node) NodeFilter.SHOW_TEXT, // durchsucht Text-Knoten null, // Platzhalter für zusätzliche Filterregeln false ); let node; // Solange unterhalb des Startelementes Nodes/Elemente zu finden sind while( node = walker.nextNode() ){ // Wenn Suchbegriff gefunden wurde in results pushen if( node.textContent.includes( text ) ){ // Array füllen mit dem Parent-Node/Eltern-Element results.push(node.parentElement); } } return results; }
Jetzt müssen wir unsere Suche bzw. das Ergebnis der Suche auslesen. Und hierbei kommt es jetzt darauf an:
- Was wollen wir als Ergebnis?
- Ausgabe: id's
- Ausgabe Classennamen
- Wie rufen wir unsere Funktion auf?
- findTxt( getObj('#wrapper') , 'Suchbegriff' ) oder
- findTxt( '#wrapper' , 'Suchbegriff' )
Denn wir wollen unseren Code ja kurz halten.
Doch hierfür müssen wir unsere Funktion noch ein kleines Bisschen anpassen:
function findTxt( myroot , text ){ // Zuweisung des Elementes für den Start der Suche const root = getObj( myroot ); ... }
Jetzt wo wir das angepasst haben sehen wir uns die Auswertung an.
Hierfür benötigen wir eine Schleife, denn das Ergebnis befindet sich ja in dem Array results.
// Ausführen const textNodes = findTxt( '#wrapper' , 'Suchbegriff'); // Array auslesen textNodes.forEach( el => { // Ausgabe für id's el.id; ... // Ausgabe für ClassName el.className; ... // Do somthing });
Ob man hier mit einer forEach() arbeiten möchte, überlasse ich Euch.
Möglich wäre auch while()
Wenn Ihr Anregungen oder Kommentare habt, seid so nett und kontaktiert mich unter: Kontakt
Kopiert Euch gerne den Code und probiert es aus: Code
Kopiert Euch die gesamte bib.js als bib.txt: Code
schenken solltest.
Gib uns alle Eletern-Elemente aus für:
Code
HTML: <div id="wrapper" class="my-wrapper"> Das ist ein Beispieltext <div id="ebene-1" class="cl-ebene-1"> dem Du <span id="span-eins" class="sp-eins">bitte keine</span> Beachtung <p id="p-1" class="p-1">schenken solltest.</p> <div id="ebene-2" class="eb-2"> Aber in diesem Beispieltext <span id="span-zwei" class="new-class">kannst Du auch</span> den Text finden. </div> </div> </div> <p class="my-fett"> Gib uns alle Eletern-Elemente aus für: </p> <form name="skillflow"> <p> Suchbegriff:<br> <select id="suche"> <option value="Beispieltext">Beispieltext</option> <option value="Du">Du</option> <option value="bitte">bitte</option> <option value="schenken">schenken</option> <option value="finden">finden</option> </select> </p> <p> Ausgabe:<br> <select id="selector"> <option value="id">id</option> <option value="className">className</option> </select> </p> </form> <div id="target"> <span>Ausgabe:</span><br> <div id="ausgabe" class="fett commentar"></div> </div> </div> <br> <button id="buttonid" class="ancor_button" name="buttonname" onclick="newAusgabe()">Ausgeben</button>
CSS: .example-wrapper select, .example-wrapper option{ color: var(--black) !important; } .my-fett{ font-weight: 600; color: rgba(112, 175, 4, 1) !important; }
JavaScript: bib.js: /* START::: getObj() */ function getObj ( identifier ) { const idfName = identifier; // Element speichern const myElem = document.querySelectorAll(idfName); // Rückgabe des Elementes if ( myElem.length === 1 ){ // Element ist eindeutig return myElem[0]; } else { // Mehrere Elemente vorhanden => Rückgabe Array return myElem; } } /* ENDE::: getObj() */ /* START::: Finde-Text */ function findTxt( myroot, text ){ const root = getObj( myroot ); const results = []; // Array für Treffer // Watch Dog starten const walker = document.createTreeWalker( root, // Start der Suche NodeFilter.SHOW_TEXT, // durchsucht Text-Knoten null, // Platzhalter für zusätzliche Filterregeln false ); let node; // Solange unterhalb des Startelementes "walker" Nodes zu finden sind while( node = walker.nextNode() ){ // Wenn Suchbegriff gefunden wurde in results pushen if( node.textContent.includes(text) ){ // Node pushen results.push(node.parentElement); } } return results; } /* ENDE::: Finde-Text */
JavaScript: function newAusgabe(){ // Auslesen der Options const myNewTx = getObj( '#suche' ).value; const myNewSel = getObj( '#selector' ).value; // Ausführen const textNodes = findTxt( '#wrapper', myNewTx ); let myNewAusgabe = ''; // Array auslesen textNodes.forEach( el => { if(myNewSel === 'id'){ // Ausgabe für id's myNewAusgabe += el.id+'
'; }else{ // Ausgabe für ClassName myNewAusgabe += el.className+'<br>'; } }); getObj('#ausgabe').innerHTML = myNewAusgabe; }