Eine Suchfunktion läuft nicht mehr

Webhufi

Erfahrenes Mitglied
Hallo,

ich hatte auf einer alten Seite - die leider verschwunden ist - eine Suche drin, die ich jetzt auf eine andere Page übernommen habe; nur diesen HTML-Teil hatte ich gerettet.
Leider funktioniert diese Suche nicht, wahrscheinlich fehlt etwas (ein Script?)

Ich erinnere mich, dass es recht einfach und ebenso kurz war, es funktionierte nur auf der Seite, in die es eingebaut war; mehr ist nicht notwendig.

Natürlich gibt es im Web solche Suchfunktionen, aber die sind mir alle zu aufgebauscht, und verstehen kann ich sie sowieso nicht.

Hat jemand eine Idee - und auch Lust dazu - diese Suche (etwas weiter unten) wieder zum Laufen zu bringen? Das würde mich sehr freuen!

Viele Grüße
Norbert
 
Lösung
Hallo Norbert, tut mir Leid, diese Sache war wieder ein wenig in den Hintergrund geraten.

Ich habe jetzt das Zurücknehmen durch Mausbewegung implementiert. Es kann passieren, dass schon direkt nach dem Klick auf den Link die Maus ein wenig bewegt wird. Daher musste ich eine Prüfung einführen, ob der Weg dabei einen bestimmten Betrag überschreitet, das ist die Konstante deltaMouse. In meiner Testdatei funktioniert es, ich hoffe, bei dir dann auch.
Code:
    <script>
        // Der Weg, um den die Maus bewegt werden muss, damit die Hervorhebung
        // des Linkziels zurück genommen wird
        const deltaMouse = 20;
        //Aktuelle Mauskorrdinaten
        let mouseX = 0, mouseY = 0,
            // Mauskoordinaten beim letzten Klick...
Ich glaube, ich verstehe nicht ganz:

Den Code habe ich geändert. Der Testlink führt zum Ende der Seite, wo das Ziel blau eingefärbt wird. Zwar verschwindet jetzt die blaue Markierung nach einem Klick irgendwohin, aber ich denke, dass kaum ein User auf die Idee eines solchen Klicks kommen wird, mich eingeschlossen; ich kam erst spät auf diesen Gedanken.

Wenn ich aber auf den Link darunter klicken möchte, also "...zurück..., dann ist eine Bewegung der Maus notwendig; damit könnte die Markierung verschwinden.

Klicke ich nun den Link an "...zurück zu diesem Eintrag", wird das Ziel nicht mehr blau hinterlegt wie vorher; ein Manko, weil wir uns auf Grund der Übersichtlichkeit gewünscht hatten, alle Ziele zu färben und danach die Färbung wieder durch eine Aktion zu entfernen; eine Klick-Aktion ist also recht ungünstig; wie vorher beschrieben, wäre eine rein intuitive Aktion hilfreicher, also eine Mausbewegung.

Möglicherweise nerve ich dich; möglicherweise siehst du das aber auch als Herausforderung! ;-)

Herzliche Grüße
Norbert
 
Hallo Norbert, tut mir Leid, diese Sache war wieder ein wenig in den Hintergrund geraten.

Ich habe jetzt das Zurücknehmen durch Mausbewegung implementiert. Es kann passieren, dass schon direkt nach dem Klick auf den Link die Maus ein wenig bewegt wird. Daher musste ich eine Prüfung einführen, ob der Weg dabei einen bestimmten Betrag überschreitet, das ist die Konstante deltaMouse. In meiner Testdatei funktioniert es, ich hoffe, bei dir dann auch.
Code:
    <script>
        // Der Weg, um den die Maus bewegt werden muss, damit die Hervorhebung
        // des Linkziels zurück genommen wird
        const deltaMouse = 20;
        //Aktuelle Mauskorrdinaten
        let mouseX = 0, mouseY = 0,
            // Mauskoordinaten beim letzten Klick auf einen Link
            clickedX = 0, clickedY = 0,
            linkClicked = false;
        function undoSearch(cls) {
            // Ueber alle Fundstellen:
            document.querySelectorAll('span.' + cls).forEach(item => {
                // Elternelement ermitteln
                const parent = item.parentNode;
                // Textknoten mit Text des Elternelementes erzeugen
                const newTxtNode = document.createTextNode(parent.textContent);
                // ... und Elternelement damit ersetzen
                parent.replaceWith(newTxtNode);
                // Jetzt hat der Knoten wieder der ursprünglichen Zustand
            });
        }
        function search(node, needle, cls) {
            const regex = new RegExp('(' + needle + ')', 'i');
            node.childNodes.forEach(node => {
                switch (node.nodeType) {
                    // Handelt es sich um einen Elementknoten?
                    case 1:
                        // Suche fortsetzen
                        search(node, needle, cls);
                        break;
                    // Handelt es sich um einen Textknoten?
                    case 3:
                        // Den Text heraus ziehen
                        const txt = node.textContent.trim();
                        // console.log(txt)
                        if (txt != '') {
                            // Um den gefundenen Text hervor zu heben, betten wir ihn ein
                            // span-Element ein, das wir dann geeignet mit CSS gestalten koennen.
                            // In einem Textknoten wird jedoch kein HTML interpretiert.
                            // Daher erzeugen wir ein neues span-Element und tragen dort den
                            // geaenderten Text ein.
                            let newEle = document.createElement('span');
                            newEle.innerHTML = txt.replace(regex, '<span class="' + cls + '">$1</span>')
                            node.replaceWith(newEle);
                            break;
                        }
                }
            });
        }
        let lastSearchStr = '',
            foundElems,
            idxSearch = 0;
        // Die folgende Funktion wird durch das Suchformular aufgerufen
        // und startet die Suche
        function suchen(needle) {
            // event.preventDefault();
            // Unterscheidet sich der Suchstring vom gespeicherten?
            // D. h. handelt es sich um eine neue Suche?
            if (needle != lastSearchStr) {
                lastSearchStr = needle;
                idxSearch = 0;
                // Aenderungen am DOM von der vorigen Suche rueckgaengig machen
                undoSearch('found');
                // Suche starten
                search(document.querySelector('body'), needle, 'found');
                // Gefundene Element bereit stellen
                foundElems = document.querySelectorAll('.found');
                // Erstes gefundenes Element hervor heben
                foundElems[idxSearch].classList.add('highlight');
                // ... und in den sichtbaren Bereich scrollen
                foundElems[idxSearch].scrollIntoView();
                searchDone = true;
            } else {
                // Hevorhebung des alten gefundenen Elementes löschen
                foundElems[idxSearch].classList.remove('highlight');
                // Sind weitere gefundene Element vorhanden?
                if (foundElems[idxSearch + 1]) {
                    // Naechstes gefundenes Element hervor heben
                    idxSearch++;
                    foundElems[idxSearch].classList.add('highlight');
                    // ... und in den sichtbaren Bereich scrollen
                    foundElems[idxSearch].scrollIntoView();
                } else {
                    // Keine weiteren gefundenen Elemente.
                    // Nachricht an Benutzer
                    let response = confirm('Keine weiteren Fundstellen vorhanden<br>' +
                        'zurück zum Suchfeld?');
                    console.log(response);
                    if (response) {
                        document.querySelector('input[name="suchtexting"]').scrollIntoView();
                    }
                }
            }
            return false;
        }
        document.addEventListener('DOMContentLoaded', function () {
            document.querySelector('form[name="search"]').addEventListener('submit', function (event) {
                event.preventDefault();
                suchen(document.querySelector('input[name="suchtexting"]').value);
            });
            document.querySelectorAll('a').forEach(item => {
                item.addEventListener('click', function (event) {
                    // Linktext als Suchstring bereit stellen
                    const needle = item.innerHTML.replace(/\s+/, ' ');
                    // Linkziel bereit stellen
                    const destId = item.href.substr(item.href.indexOf('#') + 1);
                    const dest = document.getElementById(destId);
                    // Ist der Linktext im Text des Linkziels vorhanden?
                    if (dest.textContent.includes(needle)) {
                        console.log('search');
                        // Nur den Linktext hervor heben
                        search(dest, needle, 'link-dest');
                        dest.querySelector('.link-dest').classList.add('link-dest-2');
                    } else {
                        // Das gesamte Linkziel hervor heben
                        dest.classList.add('link-dest-2');
                    }
                    clickedX = mouseX;
                    clickedY = mouseY;
                    linkClicked = true;
                });
            });
            // Eventlistener für mousemove registrieren
            document.addEventListener('mousemove', event => {
                // Mausposition in globale Variablen eintragen
                mouseX = event.clientX;
                mouseY = event.clientY;
                // Wurde zuvor ein Link geklickt und
                // wurde die Maus seitdem um den Weg deltaMouse bewegt?
                if (linkClicked &&
                    (Math.hypot(mouseX - clickedX, mouseY - clickedY) > deltaMouse)) {
                    linkClicked = false;
                    // Hervorhebung des Linkziels aufheben
                    undoSearch('link-dest');
                    const dest = document.querySelector('.link-dest-2');
                    if (dest) dest.classList.remove('link-dest-2');
                }
            });
        });
    </script>
 
Lösung
Das passt schon so, Ulrich, du hast ja auch noch anderes zu tun... ;-)

Jetzt läuft alles super! Ich habe es jetzt komplett auf meiner Originalseite stehen und habe somit keine weiteren Wünsche mehr!

Ganz herzlichen Dank für deine tolle Arbeit!!! :)

Herzliche Grüße und gute Zeit

Norbert

P.S.: PN habe ich erst eben gesehen, längere Antwort kommt noch...
 
Zurück