Friedel: JavaScript - Problem mit addEventListener

problematische Seite

Hallo, ich möchte gerne einem Button mit JavaScript Leben einhauchen. Dazu möchte ich addEventListener verwenden. Aber offensichtlich funktioniert das nicht so, wie ich erwartet habe. Die vielen Beschreibungen dazu, die ich in den letzten Stunden gelesen habe, sind offensichtlich alle voneinander abgeschrieben und kaum brauchbar.

Im Html steht nur ein Button, der disabled ist.

<button id="o1" disabled>Button</button>

Im Script habe ich jetzt stehen:

window.onload=function(){
  document.getElementById('o1').disabled=false;
  document.getElementById('o1').addEventListener('click', ordnerauf("xxx"));
};

function ordnerauf(a) {
  alert(a);
};

Ich hatte erwartet, dass der Button aktiv wird, wenn die Seite geladen ist. Das funktioniert auch. Außerdem habe ich erwartet, dass der Button einen Eventhandler bekommt, der etwa das gleiche macht, wie onClick. Wenn der Button angeklickt wird, soll die Funktion ordnerauf() aufgerufen werden. Das klappt aber nicht. ordnerauf() wird sofort aufgerufen. Wenn man den Button anklickt, passiert nichts.

Wer kann mir erklären, was ich falsch mache?

akzeptierte Antworten

  1. problematische Seite

    Hallo Friedel,

    window.onload=function(){
      document.getElementById('o1').disabled=false;
      document.getElementById('o1').addEventListener('click', ordnerauf("xxx"));
    };
    
    function ordnerauf(a) {
      alert(a);
    };
    

    Das geht so nicht, addEventListener() erwartet eine Funktionsreferenz. Was du dort tust ist ordnerauf() ausführen und dann den Rückgabewert an addEventListener() geben. Du könntest das etwa so umgehen:

    document.getElementById('o1').addEventListener('click', ordnerauf);
    

    Offensichtlich kannst du so natürlich keine Argumente übergeben. Falls das notwendig ist, könntest du mit einer anonymen Funktion arbeiten:

    document.getElementById('o1').addEventListener('click', function() { ordnerauf("xxx") });
    

    LG,
    CK

    1. problematische Seite

      Aha. Danke. So klappt es.

      1. problematische Seite

        Mist. Jetzt hab ich das nächste Problem.

        Eigentlich geht es um mehrere Buttons. Jeder hat eine id, die aus dem Buchstaben o und einer fortlaufenden Nummer besteht.

        <button id="o1">Text</button>
        <button id="o2">Text</button>
        <button id="o3">Text</button>
        <button id="o4">Text</button>
        

        Mit

        window.onload=function(){
          for(i=1; i<document.getElementsByTagName('ul').length; i++){
            document.getElementById('o'+i).addEventListener('click', function() {ordnerauf(i)});
          };
        };
        
        function ordnerauf(a) {
          alert(a);
        };
        

        wollte ich jetzt eigentlich erreichen, dass jeder Button beim Anklicken seine Nummer in der Alertbox wiedergibt. Aber jetzt geben sie natürlich alle die Nummer des letzten Buttons aus. Ich glaube, ich habe einen Knoten im Hirn. Wie macht man sowas?

        1. problematische Seite

          Hallo

          Eigentlich geht es um mehrere Buttons. Jeder hat eine id, die aus dem Buchstaben o und einer fortlaufenden Nummer besteht.

          Mit

          window.onload=function(){
            for(i=1; i<document.getElementsByTagName('ul').length; i++){
              document.getElementById('o'+i).addEventListener('click', function() {ordnerauf(i)});
            };
          };
          
          function ordnerauf(a) {
            alert(a);
          };
          

          wollte ich jetzt eigentlich erreichen, dass jeder Button beim Anklicken seine Nummer in der Alertbox wiedergibt. Aber jetzt geben sie natürlich alle die Nummer des letzten Buttons aus. Ich glaube, ich habe einen Knoten im Hirn. Wie macht man sowas?

          1. Registriere das Event an einem Elternelement aller Buttons.
          2. Ermittle das Element/den Button, der das Event ausgelöst hat, innerhalb der aufgerufenen Funktion mit event.target. Das Beispiel auf der verlinkten Wikiseite sollte selbsterklärend sein.

          Tschö, Auge

          --
          Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
          Toller Dampf voraus von Terry Pratchett
          1. problematische Seite

            Hallo Auge,

            1. Registriere das Event an einem Elternelement aller Buttons.
            2. Ermittle das Element/den Button, der das Event ausgelöst hat, innerhalb der aufgerufenen Funktion mit event.target. Das Beispiel auf der verlinkten Wikiseite sollte selbsterklärend sein.

            Ja, das ist die richtige Lösung. Molily hat darüber etwas geschrieben.

            LG,
            CK

            1. problematische Seite

              Danke. Im Moment habe ich keine Zeit mehr dafür, aber heute nachmittag geht es weiter. Ich hatte mir inzwischen mit

              document.getElementById('o'+i).addEventListener('click', function() {ordnerauf(this.id)});
              

              geholfen. Das funktioniert. Was ist der Unterschied? Mit event.target habe ich es noch nicht zum Laufen gebracht. Was ist mit

              Registriere das Event an einem Elternelement aller Buttons.

              gemeint?

              Damit kann ich nichts anfangen. Es soll doch nur dann etwas passieren, wenn einer der Buttons angeklickt wird, nicht wenn sonst irgendwo geklickt wird. Die Buttons haben zwar alle einen gemeinsamen Vorfahren, aber kein direktes Elternelement gemeinsam. Und dieser gemeinsame Vorfahr enthält natürlich sehr viel anderes, als nur die Buttons.

              1. problematische Seite

                Hallo

                Was ist mit

                Registriere das Event an einem Elternelement aller Buttons. gemeint?

                Damit kann ich nichts anfangen. Es soll doch nur dann etwas passieren, wenn einer der Buttons angeklickt wird, nicht wenn sonst irgendwo geklickt wird.

                Wie der bei Christian verlinkte Artikel von Molily erklärt, gibt es die Event Delegation. Ein Klick auf einen Button wird nicht nur bei dem Button selbst registriert (im Sinne von „bemerkt“), sondern durch das „Event Bubbling“ auch von dessen Elternelementen.

                Im Falle von vielen gleichartigen Events, wie er auch auf deine Buttonsammlung zutrifft, muss so nur ein Event registriert werden statt der N Events für jeden Button. Das verbraucht weniger Ressourcen, da erst einmal nur ein (Eltern)-Element statt der vielen Kindelemente, an denen der Event ausgelöst wird, überwacht werden muss.

                Die Buttons haben zwar alle einen gemeinsamen Vorfahren, aber kein direktes Elternelement gemeinsam. Und dieser gemeinsame Vorfahr enthält natürlich sehr viel anderes, als nur die Buttons.

                Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren. Du kannst das Event aber auch beim gemeinsamen Vorfahr registrieren und über den mit event.target ermittelten Wert prüfen, ob überhaupt ein Button betätigt wurde und nur dann den Code ausführen. Was sinnvoller ist, kommt auf eventuell vorhandene weitere Funktionen und die tatsächliche HTML-Struktur an.

                Tschö, Auge

                --
                Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
                Toller Dampf voraus von Terry Pratchett
                1. problematische Seite

                  @@Auge

                  Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren.

                  Nein, das kannst du nicht. Das gruppierende Element ist kein interaktives Element, ist also nicht allgemein bedienbar.

                  Du kannst das Event aber auch beim gemeinsamen Vorfahr registrieren und über den mit event.target ermittelten Wert prüfen, ob überhaupt ein Button betätigt wurde

                  Das kannst du machen.

                  Und zwar tatsächlich, ob ein Button betätigt wurde, nicht ein ul.

                  LLAP 🖖

                  --
                  “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                  1. problematische Seite

                    Hallo

                    Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren.

                    Nein, das kannst du nicht. Das gruppierende Element ist kein interaktives Element, ist also nicht allgemein bedienbar.

                    Ach, warum sollte das gruppierende Element interaktiv sein? Dein immer wieder vorgetragenes Mantra, Eventlistener an <body> zu binden, sind also auch falsch. <body> ist schließlich kein interaktives Element.

                    Danke für diese Klarstellung.

                    Du kannst das Event aber auch beim gemeinsamen Vorfahr registrieren und über den mit event.target ermittelten Wert prüfen, ob überhaupt ein Button betätigt wurde

                    Das kannst du machen.

                    Und zwar tatsächlich, ob ein Button betätigt wurde, nicht ein ul.

                    Ich weiß ja nicht, wo du dein ul hernimmst, von mir hast du es gewiss nicht.

                    Tschö, Auge

                    --
                    Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
                    Toller Dampf voraus von Terry Pratchett
                    1. problematische Seite

                      @@Auge

                      Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren.

                      Nein, das kannst du nicht. Das gruppierende Element ist kein interaktives Element, ist also nicht allgemein bedienbar.

                      Ach, warum sollte das gruppierende Element interaktiv sein? Dein immer wieder vorgetragenes Mantra, Eventlistener an <body> zu binden, sind also auch falsch.

                      Nein, bei event delegation registriert man das click-Event natürlich für ein nicht-interaktives Element. Da muss man dann darauf auchten, dass das Event-Target ein interaktives Element sein muss.

                      Event delegation hattest du im „Du kannst das Event aber auch“-Zweig behandelt, im „Du kannst einerseits“-Zweig (um den es hier ging) also (nach meiner Lesart) ausgeschlossen.

                      Ich weiß ja nicht, wo du dein ul hernimmst, von mir hast du es gewiss nicht.

                      Nein, das war ein Bezug auf den anderen Ast hier im Thread.

                      LLAP 🖖

                      --
                      “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                      1. problematische Seite

                        Hallo

                        Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren.

                        Nein, das kannst du nicht. Das gruppierende Element ist kein interaktives Element, ist also nicht allgemein bedienbar.

                        Ach, warum sollte das gruppierende Element interaktiv sein? Dein immer wieder vorgetragenes Mantra, Eventlistener an <body> zu binden, sind also auch falsch.

                        Nein, bei event delegation registriert man das click-Event natürlich für ein nicht-interaktives Element. Da muss man dann darauf auchten, dass das Event-Target ein interaktives Element sein muss.

                        Ja, wie nun? Nichts anderes habe ich vorgeschlagen.

                        Event delegation hattest du im „Du kannst das Event aber auch“-Zweig behandelt, im „Du kannst einerseits“-Zweig (um den es hier ging) also (nach meiner Lesart) ausgeschlossen.

                        Deine Lesart ist nicht die allgemeingültige Wahrheit.

                        Mit dem gruppierenden Element erzeuge ich einen „neuen“ Vorfahren, um das Event an ihn zu binden, falls das denn die Sache gegenüber der Nutzung eines vorhandenen Vorfahrens vereinfachen sollte. Ich habe, wie ich in meinem ursprünglichen Posting schon beschrieb, keine Kenntnis vom Quelltext des OP. Daher kann ich nicht beurteilen, ob es sinnvoll ist, das Event an ein bereits vorhandenes Vorfahrenelement zu binden, wenn da „zu viel“ Anderes dranhängt oder ob es einfacher und übersichtlicher ist, ein neues Vorfahrenelement nur für die Buttons zu erzeugen.

                        Tschö, Auge

                        --
                        Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
                        Toller Dampf voraus von Terry Pratchett
                        1. problematische Seite

                          @@Auge

                          Du kannst einerseits den Buttons in ein gruppierendes Element einschließen und das Event für dieses gruppierende Element registrieren.

                          Nein, das kannst du nicht. Das gruppierende Element ist kein interaktives Element, ist also nicht allgemein bedienbar.

                          Ach, warum sollte das gruppierende Element interaktiv sein? Dein immer wieder vorgetragenes Mantra, Eventlistener an <body> zu binden, sind also auch falsch.

                          Nein, bei event delegation registriert man das click-Event natürlich für ein nicht-interaktives Element. Da muss man dann darauf auchten, dass das Event-Target ein interaktives Element sein muss.

                          Ja, wie nun? Nichts anderes habe ich vorgeschlagen.

                          Event delegation hattest du im „Du kannst das Event aber auch“-Zweig behandelt, im „Du kannst einerseits“-Zweig (um den es hier ging) also (nach meiner Lesart) ausgeschlossen.

                          Deine Lesart ist nicht die allgemeingültige Wahrheit.

                          „Du kannst das Event aber auch beim gemeinsamen Vorfahr registrieren und über den mit event.target ermittelten Wert prüfen, ob überhaupt ein Button betätigt wurde und nur dann den Code ausführen“ hörte sich für mich wirklich an wie: du kannst aber auch event delegation einsetzen.

                          Dadurch las sich das vorige „Du kannst einerseits …“ wie: hier nicht event delegation.

                          Wenn das von dir nicht so beabsichtigt war, dann nichts für ungut.

                          LLAP 🖖

                          --
                          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                          1. problematische Seite

                            Hallo

                            „Du kannst das Event aber auch beim gemeinsamen Vorfahr registrieren und über den mit event.target ermittelten Wert prüfen, ob überhaupt ein Button betätigt wurde und nur dann den Code ausführen“ hörte sich für mich wirklich an wie: du kannst aber auch event delegation einsetzen.

                            Dadurch las sich das vorige „Du kannst einerseits …“ wie: hier nicht event delegation.

                            Wenn das von dir nicht so beabsichtigt war, dann nichts für ungut.

                            Mir ging es bei meinem Posting nur um die Möglichkeit, entweder einen vorhandenen Vorfahren anzusprechen oder, wenn das der Übersichtlichkeit dienlich ist, einen neuen zu erzeugen. @Friedel sprach ja an, dass der gemeinsame Vorfahr „sehr viel anderes, als nur die Buttons“ enthält. Ich wollte kein Entweder-Oder konstruieren.

                            Auch wenn ein zusätzliches Element nicht der reinen Lehre entsprechen mag, kann es sinnvoll sein, die Lehre Lehre sein zu lassen. Gerade in Fällen, wo ein zusätzliches Maß Übersicht eine Rolle spielt.

                            Tschö, Auge

                            --
                            Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
                            Toller Dampf voraus von Terry Pratchett
              2. problematische Seite

                @@Friedel

                Registriere das Event an einem Elternelement aller Buttons. Die Buttons haben zwar alle einen gemeinsamen Vorfahren, aber kein direktes Elternelement gemeinsam.

                Auge meinte eigentlich auch: an einem Vorfahrenelement aller Buttons.

                LLAP 🖖

                --
                “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
          2. problematische Seite

            Nein, das Beispiel auf den verlinkten Wikiseite ist leider nicht selbsterklärend und ich verstehe es auch nicht. Es wäre schön, wenn in solchen Beispielen nur eine Sache gezeigt würde. Die Beispiele sind immer sehr komplex. Ich kann damit nicht anfangen.

            Ich habe lange mit event.target rumprobiert, aber ich erreiche damit nichts brauchbares.

            Edit: Offensichtlich ist es in diesem Forum nicht möglich, dass meine Antwort im Threadbaum dort erscheint, wo sie hin gehört. Dies ist eine Antwort auf den Beitrag von Auge von 02.01.2018 10:43. Dass sie ganz wo anders steht, halte ich für einen gravierenden Bug im Forum.

            1. problematische Seite

              Hallo,

              Nein, das Beispiel auf den verlinkten Wikiseite ist leider nicht selbsterklärend und ich verstehe es auch nicht. Es wäre schön, wenn in solchen Beispielen nur eine Sache gezeigt würde. Die Beispiele sind immer sehr komplex. Ich kann damit nicht anfangen.

              meinst du diese Seite https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/target?

              Edit: Offensichtlich ist es in diesem Forum nicht möglich, dass meine Antwort im Threadbaum dort erscheint, wo sie hin gehört. Dies ist eine Antwort auf den Beitrag von Auge von 02.01.2018 10:43. Dass sie ganz wo anders steht, halte ich für einen gravierenden Bug im Forum.

              die Antwort ist genau da, wo sie hin gehört. Nur hat Christian schon vor dir geantwortet.

              Gruß
              Jürgen

            2. problematische Seite

              Hallo

              Nein, das Beispiel auf den verlinkten Wikiseite ist leider nicht selbsterklärend und ich verstehe es auch nicht.

              Aha, das ist doch mal eine Ansage.

              Es wäre schön, wenn in solchen Beispielen nur eine Sache gezeigt würde. Die Beispiele sind immer sehr komplex. Ich kann damit nicht anfangen.

              Das Beispiel auf der von mir verlinkten Wikiseite zeigt genau zwei Vorgänge (und damit einen zu wenig).

              1. Registrierung von Event-Listenern in der Funktion init.
              2. Die Funktion findeAuslöser, die bei einem Event ausgeführt werden soll. Dort drin wird mit event.target der Name des Elements ermittelt, mit dem der Event ausgelöst wurde.

              Ich habe lange mit event.target rumprobiert, aber ich erreiche damit nichts brauchbares.

              Zeige bitte, was du probiert hast und beschreibe, was nicht funktioniert. Grundsätzlich funktioniert das Beispiel im Wiki. Der einzige Schritt, der diesem Beispiel fehlt, ist der Code zur Ausführung von init. Man sollte zwar annehmen, dass dieser gedankliche Sprung jemandem, der programmieren will, möglich ist, Anfängern mag sich das aber nicht erschließen.

              Woran es bei dir tatsächlich scheitert, wird sich ohne deinen konkreten Code aber nicht ermitteln lassen.

              @Matthias Apsel: Das Beispiel zeigt tatsächlich zu wenig, statt zu viel. Ich vermute, dass dies auch der Grund ist, warum das Frickl-Beispiel dieses Artikels bei mir (Win10, Firefox 57) nicht ausgeführt wird. Ich kann dort hovern und klicken, wie mir lustig ist, ohne, dass mir irgendein Elementname angezeigt wird.

              Edit: Offensichtlich ist es in diesem Forum nicht möglich, dass meine Antwort im Threadbaum dort erscheint, wo sie hin gehört. Dies ist eine Antwort auf den Beitrag von Auge von 02.01.2018 10:43.

              Deine Antwort erscheint, wie schon JürgenB schrieb, genau dort, wo sie hingehört.

              Dass sie ganz wo anders steht, halte ich für einen gravierenden Bug im Forum.

              Ich sehe keinen Bug.

              Tschö, Auge

              --
              Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
              Toller Dampf voraus von Terry Pratchett
              1. problematische Seite

                Hallo Auge,

                @Matthias Apsel: Das Beispiel zeigt tatsächlich zu wenig, statt zu viel. Ich vermute, dass dies auch der Grund ist, warum das Frickl-Beispiel dieses Artikels bei mir (Win10, Firefox 57) nicht ausgeführt wird. Ich kann dort hovern und klicken, wie mir lustig ist, ohne, dass mir irgendein Elementname angezeigt wird.

                Die JavaScript-Beispiele funktionieren im Frickl alle nicht zuverlässig. Da müsste mal ein JS-Experte wie @Felix Riesterer (der ja auch das Frickl gebaut hat) drüberschauen. Selbst bei wirklich einfachen Sachen waren Änderungen notwendig. Beispiel:

                alt

                  <script>
                    function Ausgeben() {
                	    var zahl = Math.E;
                	    var elem = document.getElementById('Ausgabe');
                	    elem.innerHTML = 'Die Eulersche Konstante ist: '+ zahl;
                    }
                  </script>
                </body>
                

                neu

                  <script async>
                    document.addEventListener('DOMContentLoaded', function () {
                      function ausgeben() {
                        document.getElementById('ausgabe').textContent = 'Der Wert der Konstanten beträgt: ' + Math.E;
                      }
                      document.getElementById('start').addEventListener('click', ausgeben);
                    });
                  </script>
                </head>
                

                Bis demnächst
                Matthias

                --
                Rosen sind rot.
                1. problematische Seite

                  Hallo

                  Die JavaScript-Beispiele funktionieren im Frickl alle nicht zuverlässig.

                  Aha, da ich mich mit JS selten auseinandersetze, war mir halt nur dieses Beispiel untergekommen.

                  Da müsste mal ein JS-Experte wie @Felix Riesterer (der ja auch das Frickl gebaut hat) drüberschauen.

                  Ja, da muss ein Spezialexperte™️ ran. Das sind Bereiche (JS und Frickl), in denen ich mich definitiv nicht genug auskenne.

                  Tschö, Auge

                  --
                  Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
                  Toller Dampf voraus von Terry Pratchett
                  1. problematische Seite

                    Hallo Auge,

                    Ja, da muss ein Spezialexperte™️ ran. Das sind Bereiche (JS und Frickl), in denen ich mich definitiv nicht genug auskenne.

                    Ich habs mal so gemacht: https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/target Da besteht sicher immer noch Verbesserungspotenzial.

                    Bis demnächst
                    Matthias

                    --
                    Rosen sind rot.
                    1. problematische Seite

                      @@Matthias Apsel

                      Ich habs mal so gemacht: https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/target Da besteht sicher immer noch Verbesserungspotenzial.

                      Ja, z.B. bei var seite = document.querySelector('html');

                      Es macht wenig Sinn, nach der Nadel im Heuhaufen zu suchen, wenn man sie schon
                      in der Hand hat: var seite = document.documentElement;

                      Man kann sich die Zuweisung an seite auch sparen und gleich schreiben:

                      document.documentElement.addEventListener('mouseover', findeAuslöser);
                      document.documentElement.addEventListener('click', findeAuslöser);	
                      

                      Jetzt, wo die Eventhandler am html-Element hängen, passt „Auch wenn der Eventhandler im body notiert ist“ auch nicht mehr so richtig.

                      LLAP 🖖

                      --
                      “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                      1. problematische Seite

                        Hallo Gunnar Bittersmann,

                        Es macht wenig Sinn, nach der Nadel im Heuhaufen zu suchen, wenn man sie schon
                        in der Hand hat: var seite = document.documentElement;

                        Stimmt.

                        Man kann sich die Zuweisung an seite auch sparen und gleich schreiben:

                        document.documentElement.addEventListener('mouseover', findeAuslöser);
                        document.documentElement.addEventListener('click', findeAuslöser);	
                        

                        Stimmt auch, aber ich habe die Zuweisung an seite mal gelassen.

                        Jetzt, wo die Eventhandler am html-Element hängen, passt „Auch wenn der Eventhandler im body notiert ist“ auch nicht mehr so richtig.

                        Geändert.

                        Bis demnächst
                        Matthias

                        --
                        Rosen sind rot.
  2. problematische Seite

    Lieber Friedel,

    window.onload=function(){
    [...]
    };
    

    besser ist es heute anstelle von window.onload eben addEventListener auf das document-Objekt anzuwenden:

    document.addEventListener("DOMContentLoaded", function () {
      // tuwat
    });
    

    Das dafür notwendige Event lautet "DOMContentLoaded" (GrOß-/kLeInScHrEiBuNg beachten!).

      document.getElementById('o1').addEventListener('click', ordnerauf("xxx"));
    [...]
    function ordnerauf(a) {
      alert(a);
    };
    

    Wenn Du nun einem HTML-Element ein Event andichten willst, ist es nicht sinnvoll, den Rückgabewert einer Funktion zuzuweisen. Besser Du übermittelst eine Funktion selbst:

    myElement.addEventListener("click", ordnerauf);
    

    Wenn Du der das Event verarbeitenden Funktion, in Deinem Falle ordnerauf, noch einen Parameter mitgeben willst, dann geht das so:

    myElement.addEventListener(
      "click",
      function () {
        ordnerauf("abc");
      }
    );
    

    Sinnvoller wäre es allerdings, wenn die das Event verarbeitende Funktion, die ohnehin ein Eventobjekt erhält, selbst entscheiden darf, was zu tun ist:

    myElement.addEventListener(
      "click",
      function (eventObj) {
        // standard vs. IE < 9
        var myElement = eventObj.target || eventObj.srcElement;
    
        if (myElement.id) {
          ordnerauf(myElement);
        }
      }
    );
    

    Wenn ordnerauf nicht den Namen einer ID, sondern das Element selbst verarbeiten kann, wäre obige Lösung einfacher zu handhaben, da Du alle Deine Buttons mit einer simplen Schleife auf diese Funktion trainierst:

    document.addEventListener("DOMContentLoaded", function () {
    
      var uls = document.getElementsByTagName("ul");
    
      for(i = 0; i < uls.length; i++) {
    
        uls[i].addEventListener(
          "click",
          function (eventObj) {
            // standard vs. IE < 9
            var myElement = eventObj.target || eventObj.srcElement;
    
            if (myElement.id) {
              ordnerauf(myElement);
            }
          }
        );
      }
    });
    

    Wenn man jetzt ohnehin in der Funktion darauf prüft, ob das ul-Element eine ID hat, um nur dann ordnerauf auszuführen, kann man sich die Mühe sparen, allen ul-Elementen einzeln einen Listener für das click-Event einzurichten. Stattdessen registriert man einen Listener für das body-Element:

    document.addEventListener("DOMContentLoaded", function () {
    
      document.body.addEventListener(
          "click",
          function (eventObj) {
            // standard vs. IE < 9
            var myElement = eventObj.target || eventObj.srcElement;
    
            if (myElement.tagName // is not simple text node
              && myElement.tagName.match(/^ul$/i) // is <ul>
              && myElement.id // has ID
            ) {
              ordnerauf(myElement);
            }
          }
        );
      }
    });
    

    Liebe Grüße,

    Felix Riesterer.

    1. problematische Seite

      Hallo Felix Riesterer,

      && myElement.tagName.match(/^ul$/i) // is <ul>

      Warum nicht myElement.tagName == "UL"?

      Bis demnächst
      Matthias

      --
      Rosen sind rot.
      1. problematische Seite

        @@Matthias Apsel

        && myElement.tagName.match(/^ul$/i) // is <ul>

        Warum nicht myElement.tagName == "UL"?

        Weil es grundsätzlich falsch ist, ul-Elemente als Target von click-Events zu verwenden. Wegen unbenutzbar.

        LLAP 🖖

        --
        “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
      2. problematische Seite

        Lieber Matthias,

        Warum nicht myElement.tagName == "UL"?

        ist das (noch?) immer tatsächlich exakt so der Fall?

        Liebe Grüße,

        Felix Riesterer.

        1. problematische Seite

          @@Felix Riesterer

          Warum nicht myElement.tagName == "UL"?

          ist das (noch?) immer tatsächlich exakt so der Fall?

          Ja, das ist spezifiziert, dass tagName (und nodeName) Elementtypbezeichner in Großbuchstaben liefern – bei HTML wohlgemerkt. [DOM4]

          Bei XML (auch bei Verarbeitungs als XHTML) sähe das schon wieder anders aus.

          LLAP 🖖

          --
          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
          1. problematische Seite

            Lieber Gunnar,

            – bei HTML wohlgemerkt. [DOM4]

            Bei XML (auch bei Verarbeitungs als XHTML) sähe das schon wieder anders aus.

            eben deshalb verwende ich o.tagName.match(/^xyz$/i)

            Liebe Grüße,

            Felix Riesterer.

            1. problematische Seite

              @@Felix Riesterer

              Bei XML (auch bei Verarbeitungs als XHTML) sähe das schon wieder anders aus.

              eben deshalb

              Ist die Auslieferung von HTML als application/xhtml+xml ein Thema? Macht das irgendwer?

              verwende ich o.tagName.match(/^xyz$/i)

              Dann würde ich statt mit regulären Ausdrücken draufzuhauen lieber event.target.tagName.toUpperCase() verwenden (bzw. toLowerCase()).

              LLAP 🖖

              --
              “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
    2. problematische Seite

      @@Felix Riesterer

              var myElement = eventObj.target || eventObj.srcElement;
      
              if (myElement.tagName // is not simple text node
                && myElement.tagName.match(/^ul$/i) // is <ul>
      

      Das kann nicht funktionieren. (Du weißt schon, „funktionieren“ im Sinne von „funktionieren“.)

      ul ist kein interaktives Element, darf also nicht als Target herhalten. Target muss der jeweilige Button sein.

      LLAP 🖖

      --
      “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
      1. problematische Seite

        Lieber Gunnar,

        ul ist kein interaktives Element, darf also nicht als Target herhalten. Target muss der jeweilige Button sein.

        das ist richtig. Mir ist auch nicht klar, wie man das ul-Element direkt anklicken können sollte - aber der Lösungsansatz des OP schien wohl mit dieser Denkweise zunächst zufriedenstellend nutzbar zu sein. Also habe ich die direkte Umsetzung etwas vereinfacht. Vielleicht sogar kaputt gemacht, weil in den ul-Elementen sicher andere Elemente das tatsächliche event.target-Objekt sind.

        Wie vermittelst Du denn jetzt dem OP einen Lösungsansatz, der sowohl seinem Wissensstand als auch Deinen Ansprüchen gerecht wird? Zeig mal!

        Liebe Grüße,

        Felix Riesterer.

        1. problematische Seite

          @@Felix Riesterer

          Wie vermittelst Du denn jetzt dem OP einen Lösungsansatz, der sowohl seinem Wissensstand als auch Deinen Ansprüchen gerecht wird? Zeig mal!

          Wurde doch schon hier im Thread gesagt: abfragen, ob event target ein Button ist:
          if (eventObj.target.tagName === 'BUTTON') [1]

          Oder mit deinem myElement. Aber ehrlich mal, var myElement = eventObj.target || eventObj.srcElement; für IE < 9 braucht doch wohl kein Mensch mehr, oder?

          LLAP 🖖

          --
          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory

          1. bei mir heißt das immer event statt eventObj ↩︎

          1. problematische Seite

            Hallo Gunnar Bittersmann,

            wie würdest du denn im konkreten Fall (verschachtelte Listen zum Aufklappen) das HTML bauen?

            Bis demnächst
            Matthias

            --
            Rosen sind rot.
            1. problematische Seite

              @@Matthias Apsel

              wie würdest du denn im konkreten Fall (verschachtelte Listen zum Aufklappen) das HTML bauen?

              Ich hatte schon mal mit Basteln angefangen. Aber nicht, dass das schon fertig wäre …

              LLAP 🖖

              --
              “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
            2. problematische Seite

              Lieber Matthias,

              wie würdest du denn im konkreten Fall (verschachtelte Listen zum Aufklappen) das HTML bauen?

              auf Klick des Menü-Buttons der von mir betreuten Schulwebsite könntest Du das sehen.

              Liebe Grüße,

              Felix Riesterer.

              1. problematische Seite

                Hallo, inzwischen hat der Thread offensichtlich nichts mehr mit meinem Problem zu tun.

                Mit den Beschreibungen zu event.target komme ich allesamt nicht klar. Sie haben alle gemeinsam, dass sie kein brauchbares Beispiel enthalten und außer event.target noch alles mögliche andere gleichzeitig erklären wollen. Die Beispiele auf selfhtml sind wie fast alle Beispiele im neuen Selfhtml auch so. Wenn ich etwas neues lernen will, brauche ich ein Beispiel, das nur diese Sache enthält.

                Nebenbei ist mir auch nicht klar, wie ihr auf die Idee kommt, dass in anklickbare Listen haben will. Bei mir sollen ausschließlich Buttons anklickbar sein.

                1. problematische Seite

                  Hallo Friedel,

                  Mit den Beschreibungen zu event.target komme ich allesamt nicht klar. Sie haben alle gemeinsam, dass sie kein brauchbares Beispiel enthalten und außer event.target noch alles mögliche andere gleichzeitig erklären wollen. Die Beispiele auf selfhtml sind wie fast alle Beispiele im neuen Selfhtml auch so. Wenn ich etwas neues lernen will, brauche ich ein Beispiel, das nur diese Sache enthält.

                  https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/target

                  Bis demnächst
                  Matthias

                  --
                  Rosen sind rot.
                2. problematische Seite

                  Lieber Friedel,

                  Hallo, inzwischen hat der Thread offensichtlich nichts mehr mit meinem Problem zu tun.

                  das ist die hier nicht unübliche Threaddrift. Davon darfst Du Dich nicht verunsichern lassen.

                  Mit den Beschreibungen zu event.target komme ich allesamt nicht klar. Sie haben alle gemeinsam, dass sie kein brauchbares Beispiel enthalten und außer event.target noch alles mögliche andere gleichzeitig erklären wollen.

                  Nimm Dir Zeit! Die Sache ist nun einmal nicht so unkompliziert. Da braucht es Grundlagen- und Hintergrundwissen, um zu verstehen, was man da tut. Und das braucht Zeit.

                  Die Beispiele auf selfhtml sind wie fast alle Beispiele im neuen Selfhtml auch so. Wenn ich etwas neues lernen will, brauche ich ein Beispiel, das nur diese Sache enthält.

                  Wie soll das denn bitteschön gehen? Die Dinge hängen doch alle ganz eng miteinander zusammen! Du willst einen Event-Listener benutzen, willst aber vom Event-Objekt nichts wissen? Das passt nicht zusammen!

                  Nebenbei ist mir auch nicht klar, wie ihr auf die Idee kommt, dass in anklickbare Listen haben will.

                  Mea culpa. Ich war bei ordnerauf davon ausgegangen, dass Du eine Art Dateimanager darstellen willst, bei dem man den Ordnerinhalt durch Aufklappen (ordnerauf) sichtbar schalten will. Und ein Datei-Listing ist eben eine Liste.

                  Bei mir sollen ausschließlich Buttons anklickbar sein.

                  Ist ja OK. Und zu Deinem konkreten Problem hatte ich Dir auch eine konkrete Antwort geschrieben, mit Erklärung, was bei Dir falsch gelaufen ist und wie es richtig gegangen wäre. Eine Reaktion von Dir auf mein Posting habe ich dagegen nirgends gesehen...

                  Liebe Grüße,

                  Felix Riesterer.

                  1. problematische Seite

                    Und zu Deinem konkreten Problem hatte ich Dir auch eine konkrete Antwort geschrieben, mit Erklärung, was bei Dir falsch gelaufen ist und wie es richtig gegangen wäre. Eine Reaktion von Dir auf mein Posting habe ich dagegen nirgends gesehen…

                    Und wie finde ich diese konkrete Antwort? Kannst du mir Datum und Uhrzeit dieser Antwort nennen, oder einen Suchstring, damit ich mit Strg+f danach suchen kann.

                    1. problematische Seite

                      Hallo Friedel,

                      Kannst du mir Datum und Uhrzeit dieser Antwort nennen, oder einen Suchstring, damit ich mit Strg+f danach suchen kann.

                      Nein, schau dir den Threadbaum an.

                      Screenshot Threadbaum

                      Bis demnächst
                      Matthias

                      --
                      Rosen sind rot.