Ankündigung

Einklappen
Keine Ankündigung bisher.

addEventListener in for-Schleife

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • addEventListener in for-Schleife

    Hallo Gemeinde,

    ich sitze seit Tagen an einem Problem, welches für die Profis unter euch wahrscheinlich kein Problem darstellt. Ich komme aber mittlerweile nicht mehr weiter. Folgende Ausgangslage:
    Ich hole meine Daten (matches) per JSON bzw. werden sie als eine JSON-Datei geliefert. Nun habe ich ein Autocomplete-Feld, welches die Daten filtert.
    Soweit funktioniert auch alles super und die Ergebnisse werden per HTML in einer <ul><li> - Liste unter dem Autocomplete-Eingabefeld angezeigt.
    Nun möchte ich aber, dass etwas passiert, wenn ich dann einen dieser Einträge anklicke. Mein Ansatz:

    Code:
    // Liste erstellen
    const outputHtml = matches => {
        var html = "";
        for (i = 0; i < matches.length; i++) {
            html += "<li id='selectSchool"+matches[i].schul_id+"' class='ac_results'>";
            html += matches[i].name + ", " + matches[i].strasse + ", " + matches[i].plz + " " + matches[i].ort + " (" + matches[i].schul_id + ")";
            html += "</li>";
    
    //nun vergebe ich jedem Listeneintrag eine eigene ID:
    var x = document.getElementById("selectSchool"+matches[i].schul_id+"");
    console.log(x);
            }
            matchList.innerHTML = html;
    };
    //klappt bis hier wunderbar
    Jetzt möchte ich aber einen Eventlistener pro angezeigtem Listeneintrag einfügen:

    Code:
    if (matches[i] !==null) {x.addEventListener("click", function(){innerHTML += "Angeklickt!<br>"});}
    Das Ergebnis: Es gibt zwar eine Reaktion des Browsers, aber nicht die gewünschte. Es wird nicht (wie ich erwartet hatte) im angeklickten Listeneintrag "Angeklickt!" ausgegeben, sondern immer ein oder zwei Zeilen darunter und dann aber gleich 10x oder noch mehr direkt untereinander. In der Konsole kann ich auch sehen, wie vorher eine Menge Datensätze offenbar bei jedem Klick durchlaufen werden (in der JSON Datei sind ca. 800 Datensätze)

    Hat jemand vielleicht einen Hinweis, woran es haken könnte?

    Vielen Dank für Eure Zeit.

  • #2
    Zu dem Zeitpunkt, wo du document.getElementById() aufrufst, gibt es das Element noch gar nicht. Das erstellst du erst danach.

    Du behandelst übrigens nicht den Kontextwechsel nach HTML Werte solltest du nicht direkt in HTML-Code einfügen. Da du sowieso mit JavaScript Zugriff auf das DOM hast, kannst du dir den Umweg über HTML-Code auch gleich sparen und direkt mit JavaScript die Elemente anlegen und mit Werten befüllen.

    Kommentar


    • #3

      console.log(x); -> gibt mir aber die korrekten Einträge zurück.... Da steht dann hübsch untereinander: id="selectSchool123" , id="selectSchool456", ... , id="selectSchool567" und so weiter. Variable x ist also korrekt anglegt. Oder meinst du etwas anderes dabei? Der Umweg über HTML ist für mich in diesem Moment wahrscheinlich einfacher, weil leichter nach zu vollziehen für mich. JavaScript ist nicht meine Stärke leider.

      Kommentar


      • #4
        Nachdem der Code unvollständig ist, ist das nicht verifizierbar. Es ist jedenfalls ziemlich umständlich und unübersichtlich programmiert, und es fehlt die Behandlung des Kontextwechsels. Und dein innerHTML += ergibt für mich keinen Sinn, da nirgendwo im Code so eine Variable vorkommt. Aber vielleicht liegt das einfach nur daran, dass der Code unvollständig ist.

        Es wäre hilfreich, wenn du einen vollständiges, testbares und kurzes Beispiel posten könntest.

        Kommentar


        • #5
          Sehr gerne doch. Hier der gesamte Code:


          Code:
          const schoolSearch = document.getElementById('schoolSearch');
          const matchList = document.getElementById('match-list');
          //console.log(schoolSearch);
          //console.log(matchList);
          
          //Search states.json and filter it
          const schoolSearchStates = async schoolSearchText => {
              const res = await fetch('https://link-zum-server.com/search_new.php');
              const states = await res.json();
          //console.log(res);
          //Get matches to current text input
          let matches = states.filter(state => {
              const regex = new RegExp(`${schoolSearchText}`, 'gi');
              return state.name.match(regex) || state.strasse.match(regex) || state.ort.match(regex) || state.plz.match(regex);
              });
              if(schoolSearchText.length === 0) {
                  matches = [];
                  matchList.innerHTML = '';
              }
          
              outputHtml(matches);
          
          
          };
          // Show results in HTML
          const outputHtml = matches => {
              var html = "";
              for (i = 0; i < matches.length; i++) {
                  html += "<li id='selectSchool"+matches[i].schul_id+"' class='ac_results'>";
                  html += matches[i].name + ", " + matches[i].strasse + ", " + matches[i].plz + " " + matches[i].ort + " (" + matches[i].schul_id + ")";
                  html += "</li>";
          
          var x = document.getElementById("selectSchool"+matches[i].schul_id+"");
          console.log(x);
          if (matches[i] !==null) {x.addEventListener("click", function(){innerHTML += "Clicked!<br>"});}
               }
                  matchList.innerHTML = html;
          };
          schoolSearch.addEventListener('input', () => schoolSearchStates(schoolSearch.value));

          Kommentar


          • #6
            Da kommt folgender Fehler:

            Uncaught TypeError: schoolSearch is null
            https://jsfiddle.net/c0dem0nkey/5603ept8/

            Kommentar


            • #7
              bei mir kommt dieser Fehler:
              Code:
              Uncaught (in promise) TypeError: Cannot read properties of null (reading 'addEventListener')
                  at outputHtml (autocomplete.js:37)
                  at schoolSearchStates (autocomplete.js:22)
              was diese beiden Zeilen betrifft:
              Zeile 37: if (matches[i] !==null) {x.addEventListener("click", function(){innerHTML += "Clicked!<br>"});}
              Zeile 22: outputHtml(matches);


              Ich habe jetzt folgendes geändert: Ich prüfe die Variable x auf null, dann läuft der Code wieder durch und die Ergebnisse werden ohne Fehlermeldung angezeigt, allerdings passiert nichts beim click.
              Code:
              if (x !==null) {x.addEventListener("click", function(){innerHTML += "Clicked!<br>"});}

              Kommentar


              • #8
                Tja, für mich nicht nachvollziehbar. Der Code wirft einen anderen Fehler. Vermutlich weil in deinem Beispielcode kein Element mit der ID schoolSearch existiert.

                Kommentar


                • #9
                  Soweit funktioniert auch alles super und die Ergebnisse werden per HTML in einer <ul><li> - Liste unter dem Autocomplete-Eingabefeld angezeigt.
                  Nun möchte ich aber, dass etwas passiert, wenn ich dann einen dieser Einträge anklicke. Mein Ansatz:
                  ich rate dir hier zu handlebars (wenigstens)
                  https://handlebarsjs.com/
                  um brauchbar mit templates arbeiten zu können, sowie zu event delagtion:
                  https://molily.de/js/event-handling-effizient.html
                  um das ganze etwas einfacher, sauberer und übersichtlicher zu geastalten

                  Kommentar


                  • #10
                    wenn dein html-text noch nicht an DOM angeschloßen war kannst du den ElemenById nicht bekommen.
                    und wenn du innerHTML mit += überschreibs, verlierst du da drin schon exsistirende Elemente neu (vermmute ich).
                    Signaturrrrrrr

                    Kommentar


                    • #11
                      Lieben Dank für eure Hinweise. Es bedeutet also, dass es so mit der For-Schleife nichts wird mit addEventListener, verstehe ich das richtig? Ich hatte das Gefühl, ich stehe kurz davor, es so lösen zu können.

                      Kommentar


                      • #12
                        und mein Bauchgefühl sagt - schlechter Trick, um mit fremdem Code plus nichts tun, alles fertig zu bekommen.
                        Aber wenn du schon sooo kurz vorm Lösen stehst, dann erwarten wir ungeduldich auf die Ergebnisse.
                        Signaturrrrrrr

                        Kommentar


                        • #13
                          K313 -- Ich wusste nicht, dass Codebeispiele, die gut funktionieren und in Tutorials angeboten werden, ein Trick wären/sind. Den Sarkasmus verstehe ich, aber ich sagte ja bereits, dass JavaSricpt nicht gerade mein Spezialgebiet ist - sonst müsste ich mich nicht an dieses Forum wenden. Hier hoffe ich, dass andere, erfahrenere Programmierer ein paar gute hilfreiche Tipps haben, Hilfestellung leisten, ohne jedes Mal wieder darauf hinzuweisen, dass man lieber Grundlagen lernen sollte. Wenn ich alle Grundlagen hätte, würde ich mich nicht an das Forum hier wenden, sondern könnte alles alleine. Außerdem möchte ich mir das "nichts tun" verbitten! Seit Tagen sitze ich an diesem Problem und recherchiere auch anderweitig, lerne auch dazu - ich erwarte nicht, dass jemand den Code fertig schreibt! Du bist ein bisschen anmaßend, wenn ich das so sagen darf, aber das kenne ich auch aus anderen Foren. Wenn ihr Fachleute lieber unter euch bleiben möchtet - warum ist dieses Forum für Anfänger wie mich dann überhaupt erreichbar?
                          Finde ich jedesmal blöd, diese Diskussion, aber sie kommt halt immer wieder vor.

                          Im Übrigen überschreibe ich mit
                          Code:
                          innerHTML +=
                          nichts, sondern füge es hinzu. Dafür steht ja das + vor dem =

                          Was ich mittlerweile begriffen habe: auf die Werte aus "match" kann ich nur innerhalb der Schleife zugreifen. Das bedeutet: der EventListener muss auch zwingend innerhalb der Schleife passieren. Mit
                          Code:
                          if (x !== null)
                          umgehe ich die anfänglichen "leeren" ersten Ergebnisse - aber trotzdem "greift" der Listener noch nicht. Theoretisch sollte es gehen, aber aber aber Deswegen bin ich hier und erbitte eure Hilfe.

                          Ich werde auf jeden Fall die Hinweise von tomBuilder ansehen und angehen. Immerhin ein Hinweis.

                          Kommentar


                          • #14
                            Zitat von estebu Beitrag anzeigen
                            Im Übrigen überschreibe ich mit
                            Code:
                            innerHTML +=
                            nichts, sondern füge es hinzu. Dafür steht ja das + vor dem =
                            Ein += baut den kompletten Inhalt neu auf. Das ist auch unter anderem der Grund, warum ich dir geraten habe direkt das DOM zu manipulieren, statt HTML-Code zusammen zu basteln. Aber OK, wenn du das alles einfach ignorierst, dann brauchst du dich nicht wundern, wenn du Probleme hast.

                            Zitat von estebu Beitrag anzeigen
                            Was ich mittlerweile begriffen habe: auf die Werte aus "match" kann ich nur innerhalb der Schleife zugreifen. Das bedeutet: der EventListener muss auch zwingend innerhalb der Schleife passieren. Mit
                            Code:
                            if (x !== null)
                            umgehe ich die anfänglichen "leeren" ersten Ergebnisse - aber trotzdem "greift" der Listener noch nicht. Theoretisch sollte es gehen, aber aber aber Deswegen bin ich hier und erbitte eure Hilfe.
                            Du stellst irgendwelche Annahmen auf, die du dir selber ausdenkst, und ignorierst gleichzeitig alle Ratschläge von erfahrenen Entwicklern. Wie bereits gesagt gehst du einen unnötigen Umweg über HTML-Code, er alles komplizierter und schwerer verständlich macht, und du die Folgen (noch) nicht verstehst. Es wäre wirklich einfacher, wenn du direkt mit DOM-Manipulation arbeiten würdest.

                            Und du hast bis jetzt immer noch kein vollständigen Beispiel-Code gezeigt, mit dem sich deine Probleme nachstellen lassen. Das ist auch etwas, an dem du arbeiten solltest. Also nur Code in einem Forum posten, den du auch selber ausprobiert hast, und nicht nur irgendwelche Ausschnitte davon, die alleine gar nicht lauffähig sind.

                            Kommentar


                            • #15
                              Das stimmt nicht! Ich habe den vollständigen Code bereits gepostet (siehe oben) - habe nur lediglich die Quelle der JSON Daten anonymisiert. Der Code ist durchaus lauffähig und ich habe jetzt keine Lust her, mich ständig zu rechtfertigen. Danke für eure Zeit. Einige Hinweise werde ich mitnehmen.

                              Kommentar

                              Lädt...
                              X