Eine Suchfunktion läuft nicht mehr


Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

Sempervivum

Erfahrenes Mitglied
... 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.
 

Webhufi

Erfahrenes Mitglied
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.
 

Sempervivum

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

Webhufi

Erfahrenes Mitglied
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.
 

Sempervivum

Erfahrenes Mitglied
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:

Webhufi

Erfahrenes Mitglied
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.
 

Sempervivum

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

Webhufi

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

Sempervivum

Erfahrenes Mitglied
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)
 

Webhufi

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

Sempervivum

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

Webhufi

Erfahrenes Mitglied
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...
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

Neue Beiträge

Forum-Statistiken

Themen
272.351
Beiträge
1.558.596
Mitglieder
187.824
Neuestes Mitglied
Danke!