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...
... Versuche dieses Javascript:
Code:
    <script>
        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) {
                    const needle = item.innerHTML.replace(/\s+/, ' ');
                    const destId = item.href.substr(item.href.indexOf('#') + 1);
                    console.log(destId)
                    const dest = document.getElementById(destId);
                    search(dest, needle, 'link-dest');
                    dest.querySelector('.link-dest').classList.add('link-dest-2');
                });
            });
            document.addEventListener('click', event => {
                if (event.target.tagName != 'A') {
                    undoSearch('link-dest');
                }
            });
        });
    </script>
und dieses CSS:
Code:
        .link-dest-2 {
            background-color: lightblue;
        }
anstelle des mit :target.
Die Hervorhebung des Linkziels wird dann mit Klick irgend wo aufgehoben.
 
Hallo Ulrich,

auf der Testseite funktioniert es nicht (TESTLINK).

Auch andere Links, die auf die Realseite führen, haben jetzt dieses blau nicht mehr - in meiner Vorschau wohlgemerkt, da ich die Page noch nicht hochgeladen habe! (Die 'Struktur ist ja noch nicht fertig).

Nun habe ich das vorige Script und die beiden alten CSS wieder in die Realseite eingefügt: higlight auf der Realseite ist wieder okay, auch von den Links der Testseite aus.

Auf der Testseite das neue Script + neues CSS dringelassen, zusätzlich das mit dem target wieder eingefügt: Highlight zum target funktioniert, und auch wieder zurück.
Nur das Ausschalten per Klick geht nicht.

Also entweder liegt es am neuen CSS oder dem Script, wobei ich leider keinen Unterschied zum vorigen Script finde, sonst hätte ich ja selbst mal ein wenig herumprobieren können.
 
Es kann auf der Testseite nicht funktionieren, weil die Links absolut sind und auf die Originalseite führen, z. B.:
<a href="die-zeit-eine-ungewoehnliche-betrachtung.html?page-id=786#a5094">Bürgerliche Zeit</a>
 
Stimmt! Aber der explizite Link für Dich am Anfang der Testseite, der zum Ende der Page führt und von dort wieder zurück, ist maßgebend für meinen Test. Diese Testseite soll also veranschaulichen, dass nur genau diese beiden Links für Dich nicht das Ergebnis erzielen, das wir uns gewünscht haben. Nur diese beiden Links sollten für dich möglicherweise interessant sein.

"Übersehe" somit bitte die Links auf die Realseite, denn dort kann es noch nicht klappen, weil ich noch nicht fertig bin dort und die Page nicht erneuern kann, bevor alles stimmt.
 
Verstehe. Mit dem Testlink scheitert es jetzt an folgendem:
1. Die Testseite hat kein Formular für die Suche, daher kommt es zu einem Laufzeitfehler beim Registrieren des Eventlisteners für die Suche. Abhilfe, indem Du das betr. Javascript auskommentierst:
Code:
// davor alles wie zuvor
        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 => {
// danach alles wie zuvor
Das neue Skript sucht dem Linktext im Linkziel, weil sich dieser bei dem Testlink unterscheidet, wird er nicht gefunden. Abhilfe, indem Du den Linktext des Testlinks anpasst:
Code:
<a href="test-mit-ueberschriften.html#a6439" target="">Testlink</a>
Weitere Feinheiten, z. B. Groß-/Kleinschreibung ignorieren, können wir machen, wenn es so weit funktioniert.
 
Zuletzt bearbeitet:
Ich habe einfach die Suche in die Testseite kopiert, womit das Linkziel blau wird; damit wird die Realseite nachgestellt. Dann habe ich den Style mit target auskommentiert: das Blau ist weg; also wieder aktiviert, schau bitte.
Möglicherweise liegt es am neuen Style, der ja das Blau wieder ausschalten sollte nach einem Klick irgendwohin, in Verbindung mit dem neuen Skript?

Sonstige Anpassungen sind nicht notwendig! Unser Bestreben ist ja nur das Ziel beim Verlinken blau zu färben und die Färbung wieder abzuschalten (vielleicht besser beim Scrollen statt bei einem Klick?). Ob das bei der Suchfunktion sinnvoll ist, glaube ich eher nicht; zumal dort ja nur das Enter zum Weitersuchen nötig ist.
 
Hallo Norbert, tut mir Leid, meine Aufmerksamkeit war in den letzten Tagen durch einige nicht-technische Dinge absorbiert, so dass ich dies aus den Augen verloren hatte.
Versuche dieses Javascript:
Code:
        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);
                    console.log(destId)
                    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 {
                        console.log('add class');
                        // Das gesamte Linkziel hervor heben
                        dest.classList.add('link-dest-2');
                    }
                });
            });
            document.addEventListener('click', event => {
                if (event.target.tagName != 'A') {
                    // Nur wenn nicht auf einen Link geklickt wurde:
                    // Hervorhebung des Linkziels aufheben
                    console.log('undo');
                    undoSearch('link-dest');
                    const dest = document.querySelector('.link-dest-2');
                    if (dest) dest.classList.remove('link-dest-2');
                }
            });
        });
Beste Grüße und einen schönen Sonntag - Ulrich
 
Hallo Ulrich,

o je, das sieht nach privaten Problemen aus... Ich hoffe, du konntest sie regeln!

Auf der Testpage bleiben die beiden TESTLINKS nach wie vor blau und verschwinden weder durch Klick irgendwohin noch durch einen Mousescroll.

Zur Erinnerung: es geht nicht um die Suchfunktion, sondern nur um die Links!

Mach dir aber bitte keine Hektik; ich habe eh noch genug zu tun auf der Originalpage...

Viele Grüße
Norbert
 
Den Grund, warum es nicht funktioniert, habe ich ohne Hektik gefunden: Da fehlt noch ein wenig CSS.
Das :target muss raus und statt dessen müssen wir das Element auf Grund der Klasse link-dest-2 einfärben:
Code:
 <style>
/*    div:target { */
      div.link-dest-2 {
            background-color: lightblue !important;
        }
 </style>
(ab Zeile 188)
 
Zurück