Felix Riesterer: angeklicktes Unterelement aus <li onclick=xyz bestimmen

Liebe Selfer,

ich habe mir einen Verzeichnisbaum serverseitig als verschachtelte Liste ausgeben lassen. Um nun diesen Baum Explorer-like auf und zuklappen zu können, habe ich alle <li>s mit onclicks versehen. Alle vergleichbaren Javascripte, die ich im Netz gefunden habe, wurden ab 500 Dateieinträgen immer seeeeeeehr laaaaangsam. ;-) Durch meinen Weg wollte ich erreichen, dass die Seite nach dem Laden schnellstmöglich benutzbar wird.

Codebeispiel zur Veranschaulichung:

<ul class="explorer_baum">  
  <li class="auf" onclick="aufzu(this)"><a href="javascript:auswahl(['ordner','/html/']);"><img src="icons/folder.gif" alt="icon" />html</a>  
    <ul>  
      <li class="zu" onclick="aufzu(this)"><a href="javascript:auswahl(['ordner','/html/admin/']);"><img src="icons/folder.gif" alt="icon" />admin</a>  
        <ul>  
          <li class="file"><a href="javascript:auswahl(['datei','/html/admin/index.html/']);"><img src="icons/htm.gif" alt="icon" />index.html</a></li>  
        </ul>  
      </li>  
      <li class="file"><a href="javascript:auswahl(['datei','/html/index.html/']);"><img src="icons/htm.gif" alt="icon" />index.html</a></li>  
    </ul>...

Mein bereits gelöstes Problem:
Dadurch, dass die <li>s den Eventhandler haben, feuern sie immer, egal was ich innerhalb anklicke. Diese Lösung war nötig, damit die per CSS vorgeschalteten |+| vor den Ordnern (Hintergrundbilder) sich ebenso Explorer-like verhalten. Damit übergeordnete <li>s aber nichts bewirken habe ich eine Art Filter gebaut, der nur das tatsächlich angeklickte <li> faltet, da sonst logischerweise immer der komplette Baum zusammenklappt, wenn man einen Ordner öffnen oder schließen möchte.

Mein offenes Problem:
Ich kann keinen Filter entwickeln, der es verhindert, dass Ordner zusammengefaltet werden, wenn auf Dateien in ihnen geklickt wird (da die Datei ja auch innerhalb eines <li>s mit onclick sitzt!), was natürlich sehr stört.

Was ich suche:
Mir würde eine Möglichkeit nützen festzustellen, was innerhalb des <li> tatsächlich angeklickt wurde. Im Moment denke ich über das Abfangen von den Koordinaten des Mauszeigers nach, um davon auf das Angeklickte selbst zu schließen. Denn wenn es sich nicht um das |+| vor dem Ordnersymbol handelt, dann soll nix gefaltet werden!

Wer kann mir helfen weiterzudenken? Freue mich schon auf Anregungen. :-)

Liebe Grüße aus Ellwangen,

Felix Riesterer.

  1. Hallo Felix,

    Mein offenes Problem:
    Ich kann keinen Filter entwickeln, der es verhindert, dass Ordner zusammengefaltet werden, wenn auf Dateien in ihnen geklickt wird (da die Datei ja auch innerhalb eines <li>s mit onclick sitzt!), was natürlich sehr stört.

    Hast du mein Aufklappmenü mal getestet? Wenn du was mit 500 Dateieinträgen auf Lager hat, dann teste es doch mal, das würde mich auch interessieren. Mein Skript ist ja mit fünf Codezeilen schnell eingebunden.

      
    <link href="tree/tree.css" rel="stylesheet">  
    <script src="tree/tree.js" type="text/javascript" language="JavaScript"></script>  
    <!--[if IE]>  
    <script src="tree/ie.js" type="text/javascript" language="JavaScript"></script>  
    <![endif]-->  
    
    

    Die Liste als solche muss nur valide sein und jeweils als ertses einen Link zur Datei oder dem Ordner enthalten; alle Klassen und Eventhandler generieren sich dann dynamisch von alleine.

    Gruß Gernot

    1. Hallo nochmal,

      ich vergaß:

      Mein Ordner mit allen externen CSS- und JS-Dateien sowie den Hintergrundgrafiken als ZIP:

      http://www.sprachlernspiele.de/selftests/klappmenue/tree.zip

      Gruß Gernot

      1. Lieber Gernot,

        Dein Klappmenü wurde bei 1207 Elementen in einer verschachtelten Liste ungefähr genauso unerträglich langsam, wie andere solche Systeme auch. Das Testsystem war ein älterer Pentium III mit ca. 650MHz, auf dem sowohl der FF als auch der IE mehr als 37 Sekunden brauchten, bis die Seite benutzbar war.  So lange dauert es, bis die Scripte ihren HTML-Code um die Elemente herum generiert haben. Daher habe ich das serverseitig lösen wollen, damit es "nur" bei der Übertragung länger dauert. Im Browser ist das JS einfach wesentlich langsamer, als das PHP auf dem Server!

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

        1. Hallo Felix,

          aber dein eigentliches Problem des "Filterns" könntest du doch mit cancelBubble resp. stopPropagation geknüpft an ein Unter-Element des LI-Elements trotzem lösen, oder ist es möglicherweise geanu das dynamische Zuweisen der Eventhandler, was es so langsam macht?

          Sollte dem so sein, dann glaube ich kaum, dass es überhaupt eine Lösung für dich gibt. Wenn du überall die Eventhandler von Hand einträgst (eigentlich indiskutabel) oder serverseitig generierst bin ich auch skeptisch, ob es schneller würde.

          Gruß Gernot

          1. Lieber Gernot,

            anhand meines Codebeispieles siehst Du den serverseitig generierten Code. Da wird nix dynamisch mit Javascript gemacht. Wenn ich dann klicke, dann tut sich was JS-seitiges. Und genau da sitzt mein Problem.

            aber dein eigentliches Problem des "Filterns" könntest du doch mit cancelBubble resp. stopPropagation geknüpft an ein Unter-Element des LI-Elements trotzem lösen.

            Dieses verstehe ich nicht. Wie verwende ich das? cancelBubble und stopPropagation kommen in der SelfHTML-Doku nicht vor...

            Stelle Dir vor, du klickst auf einen Link, der in einem <li> sitzt. Bevor im <a> der href="javascript:tuewas()" ausgeführt werden kann, feuert erst der onclick des <li>, der den Ordner zuklappt (indem das übergeordnete <ul> mit display:none versehen wird), obwohl er das jetzt gerade nicht soll. Aber wie mache ich denn der durch onclick aufgerufenen Funktion klar, dass sie in diesem Falle stillhalten soll? Da müsste ich schon wissen, wo _genau_ ich innerhalb des <li> hingeklickt habe. Aber wie kriege ich das raus?

            Liebe Grüße aus Ellwangen,

            Felix Riesterer.

            1. hi,

              Stelle Dir vor, du klickst auf einen Link, der in einem <li> sitzt. Bevor im <a> der href="javascript:tuewas()" ausgeführt werden kann, feuert erst der onclick des <li>

              das ist nur logisch, weil die eventhandler nun mal vor den "normalen HTML-reaktionen" (hier: befolgen des href-inhaltes) abgearbeitet werden - auch wenn sie auf "höherer ebene", also in einem vorfahrenelement, notiert sind. nennt sich bekanntlich "event bubbling".

              hast du schon mal probiert, auf diesem <a> auch mit onClick zu arbeiten, anstatt javascript über href aufzurufen (was btw. schon ganz allgemein ein ziemliches pfui ist)?

              dann sollte zuerst mal _dieses_ onClick abgearbeitet werden, bevor das der vorfahrenelemente "an der reihe" ist.

              gruß,
              wahsaga

              --
              /voodoo.css:
              #GeorgeWBush { position:absolute; bottom:-6ft; }
              1. Lieber wahsaga,

                danke für Deine Erklärungen bezüglich des event bubblings.

                hast du schon mal probiert, auf diesem <a> auch mit onClick zu arbeiten, anstatt javascript über href aufzurufen (was btw. schon ganz allgemein ein ziemliches pfui ist)?

                Dieses "allgemein ziemliche pfui" ist für meinen persönlichen Adminbereich, den ich einmal als völlig JS-freie Seite, und einmal als durch und durch verscriptete Seite habe(n möchte). Also nix mit pfui! Auf den "regulären" Content-Seiten würden solche JS-Links _niemals_ eingesetzt. Das ist mir inzwischen auch bekannt.

                dann sollte zuerst mal _dieses_ onClick abgearbeitet werden, bevor das der vorfahrenelemente "an der reihe" ist.

                Da bringst Du mich allerdings tatsächlich auf eine Idee: Warum denn (auch wenn's nur für mich mit garantiert verfügbarem JS ist) überhaupt als JS-Link anstatt eines weiteren onClicks lösen? Den kann ich ja dann verwenden, um andere Events per bubble-stopping (oder so ähnlich - je nach Browser vermute ich?) zu vermeiden. Mein Code müsste im HTML also so aussehen:

                Codebeispiel zur Veranschaulichung:

                <ul class="explorer_baum">  
                  <li class="auf" onclick="aufzu(this)"><a href="javascript:auswahl(['ordner','/html/']);"><img src="icons/folder.gif" alt="icon" />html</a>  
                    <ul>  
                      <li class="zu" onclick="aufzu(this)"><a href="#" onclick="return auswahl(['ordner','/html/admin/']);"><img src="icons/folder.gif" alt="icon" />admin</a>  
                        <ul>  
                          <li class="file"><a href="#" onclick="return auswahl(['datei','/html/admin/index.html/']);"><img src="icons/htm.gif" alt="icon" />index.html</a></li>  
                        </ul>  
                      </li>  
                      <li class="file"><a href="#" onClick="return auswahl(['datei','/html/index.html/']);"><img src="icons/htm.gif" alt="icon" />index.html</a></li>  
                    </ul>...
                

                Ich werde das morgen mal ausprobieren. WAAAS?? Schon nach Mitternacht? Also... heute ausprobieren.

                Liebe Grüße aus Ellwangen,

                Felix Riesterer.

                1. hi,

                  Da bringst Du mich allerdings tatsächlich auf eine Idee: Warum denn (auch wenn's nur für mich mit garantiert verfügbarem JS ist) überhaupt als JS-Link anstatt eines weiteren onClicks lösen?

                  ja, das frag ich mich auch :-)
                  (und auch das <a> kann dann ggf. gegen ein anderes element ersetzt werden - wenn keine href-aktion notwendig ist, wozu dann ein <a>? <span> o.ä. tut's auch. es sei denn, man möchte es zwecks :hover-effekt im IE behalten ...)

                  Den kann ich ja dann verwenden, um andere Events per bubble-stopping (oder so ähnlich - je nach Browser vermute ich?) zu vermeiden.

                  das event bubbling wird abgebrochen, sobald du irgendwo aus einem eventhandler heraus per return false zurückgibst.

                  gruß,
                  wahsaga

                  --
                  /voodoo.css:
                  #GeorgeWBush { position:absolute; bottom:-6ft; }
                  1. Lieber wahsaga, lieber Gernot,

                    das event bubbling wird abgebrochen, sobald du irgendwo aus einem eventhandler heraus per return false zurückgibst.

                    das verhält sich bei mir irgendwie anders... Wenn ich die per onClick aufgerufene Funktion mit "return false" beende, dann wird der Eventhandler des nächsthöheren Elements aufgerufen! Hätte ich im onClick-Attribut besser onClick="RETURN meine_funbction();" schreiben sollen?

                    Jedenfalls habe ich mein Vorhaben mit Hilfe zweier globaler Variablen lösen können. Eine Variable ist sozusagen ein Trigger, die andere enthält die Verschachtelungstiefe des am tiefsten verschachtelten <li>s, so dass ich für jedes <li> prüfen kann, ob es das am tiefsten verschachtelte ist (die am tiefsten verschachtelten Elemente werden ja von solch einem Eventhandler zuerst abgeklappert!). Vielleicht wäre das mit Gernots Vorschlag eleganter zu lösen gewesen, aber Gernots Vorschlag habe ich immer noch nicht verstanden... :-(

                    Liebe Grüße aus Ellwangen,

                    Felix Riesterer.

                    1. hi,

                      das event bubbling wird abgebrochen, sobald du irgendwo aus einem eventhandler heraus per return false zurückgibst.
                      das verhält sich bei mir irgendwie anders... Wenn ich die per onClick aufgerufene Funktion mit "return false" beende, dann wird der Eventhandler des nächsthöheren Elements aufgerufen!

                      wenn nur die funktion return false zurückgibt, reicht das nicht aus.

                      Hätte ich im onClick-Attribut besser onClick="RETURN meine_funbction();" schreiben sollen?

                      ja, wie ich sagte: _aus dem eventhandler heraus_ muss false zurückgegeben werden, um die verarbeitungskette zu unterbrechen.

                      gruß,
                      wahsaga

                      --
                      /voodoo.css:
                      #GeorgeWBush { position:absolute; bottom:-6ft; }
                      1. Lieber wahsaga,

                        Hätte ich im onClick-Attribut besser onClick="RETURN meine_funbction();" schreiben sollen?

                        ja, wie ich sagte: _aus dem eventhandler heraus_ muss false zurückgegeben werden, um die verarbeitungskette zu unterbrechen.

                        also dann eher so?
                        <a href="javascript:void(0);" onClick="meine_function(); return false;">link</a>

                        Liebe Grüße aus Ellwangen,

                        Felix Riesterer.

                        1. hi,

                          also dann eher so?
                          <a href="javascript:void(0);" onClick="meine_function(); return false;">link</a>

                          wenn deine funktion selber mittels return etwas zurückgibt, wwas auf den weiteren ablauf einfluss haben soll, dann eher das genannte onClick="return meine_function();"

                          und noch mal: wenn du da nicht wirklich ein <a> brauchst - im auch im IE per CSS einen :hover-effekt zu erreichen o.ä. - dann gibt es sicher ein günstigeres element an dieser stelle, bspw. einen <span> mit onClick - ohne sinnleeres href-attribut.

                          gruß,
                          wahsaga

                          --
                          /voodoo.css:
                          #GeorgeWBush { position:absolute; bottom:-6ft; }
                          1. Lieber wahsaga,

                            wenn deine funktion selber mittels return etwas zurückgibt, wwas auf den weiteren ablauf einfluss haben soll, dann eher das genannte onClick="return meine_function();"

                            Das verhält sich bei mir anders! Meine Liste sieht ungefähr so aus:

                              
                            <ul class="explorer_baum">  
                              <li class="zu" onclick="aufzu(this)"><a href="javascript:void(0);" onclick="return auswahl(['ordner','/html/']);"><img src="icons/folder.gif" alt="icon" />html</a>  
                                <ul>  
                                  <li class="zu" onclick="aufzu(this)"><a href="javascript:void(0);" onclick="return auswahl(['ordner','/html/admin/']);"><img src="icons/folder.gif" alt="icon" />admin</a>  
                                    <ul>  
                                      <li class="zu" onclick="aufzu(this)"><a href="javascript:void(0);" onclick="return auswahl(['ordner','/html/admin/icons/']);"><img src="icons/folder.gif" alt="icon" />icons</a></li>  
                                      <li class="file"><a href="javascript:void(0);" onclick="return auswahl(['datei','/html/admin/icons/default.gif']);"><img src="icons/img.gif" alt="icon" />default.gif</a></li>  
                                    </ul>  
                                  </li>  
                                  <li class="file"><a href="javascript:void(0);" onclick="return auswahl(['datei','/html/admin/accountdirektor.script.inc']);"><img src="icons/inc.gif" alt="icon" />accountdirektor.script.inc</a></li>  
                                  <li class="file"><a href="javascript:void(0);" onclick="return auswahl(['datei','/html/admin/admin.php']);"><img src="icons/php.gif" alt="icon" />admin.php</a></li>  
                                </ul>  
                              </li>  
                            ...
                            

                            Die betroffene JS-Funktion ist das hier:

                              
                             function aufzu(element)  
                             {  
                             if(element.className == 'auf')  
                                {  
                                element.className = "zu";  
                                element.childNodes[0].childNodes[0].src = "icons/folder.gif";  
                                }  
                              else  
                                {  
                                element.className = "auf";  
                                element.childNodes[0].childNodes[0].src = "icons/folderopen.gif";  
                                }  
                             return false;  
                             }
                            

                            Wenn ich jetzt auf einen Ordner klicke (also auf ein <li>-Element), dann reagiert der darin enthaltene Eventhandler und wechselt die CSS-Klasse. Das übergeordnete <li> tut das aber auch! Obwohl mein Eventhandler (s.o.) onclick="return aufzu(this);" lautet und die Funktion aufzu() ein false zurückliefert!

                            und noch mal: wenn du da nicht wirklich ein <a> brauchst - im auch im IE per CSS einen :hover-effekt zu erreichen o.ä. - dann gibt es sicher ein günstigeres element an dieser stelle, bspw. einen <span> mit onClick - ohne sinnleeres href-attribut.

                            Ja, ich brauche den Hover-Effekt im IE!

                            Dass bei mir das bubbling nicht gestoppt wird, liegt vielleicht daran, dass ich Gernots Herangehensweise nicht verstanden habe, daher auch nicht umsetzen konnte... :-(

                            Liebe Grüße aus Ellwangen,

                            Felix Riesterer.

                            1. Hallo Felix,

                              <li class="zu" onclick="aufzu(this)"><a href="javascript:void(0);" onclick="return auswahl(['ordner','/html/']);"><img src="icons/folder.gif" alt="icon" />html</a>

                              Dass bei mir das bubbling nicht gestoppt wird, liegt vielleicht daran, dass ich Gernots Herangehensweise nicht verstanden habe, daher auch nicht umsetzen konnte... :-(

                              Also ich bin ja selbst gespannt, ob Wahsagas Ansatz, der ja viel einfacher klingt, auch funktioniert und letztlich mit einem einfachen return false dasselbe tut wie meine Funktion.

                                
                              function stp (e) {  
                                if(e) {  
                                   e.stopPropagation();  
                                } else {  
                                  window.event.cancelBubble = true;  
                                }  
                              }  
                              
                              

                              Nach meinem Ansatz würdest du diese Funktion in deiner Funktion auswahl() aufrufen und da (dann natrlich ganz am Ende) sollte meines Erachtens auch das von Wahsaga vorgeschlagene return false hin und nicht in deine Funktion aufzu(); du willst doch verhindern, dass das LI-Elternelement vom Klick auf das Link-Kindelement mitbetroffen wird. Also muss da auch das Weiterblubbern des Events gestoppt werden.

                              Gruß Gernot

                              P.S. Bei meiner Version lässt du das return im Eventhandler des Links natürlich weg.

            2. Hallo Felix,

              aber dein eigentliches Problem des "Filterns" könntest du doch mit cancelBubble resp. stopPropagation geknüpft an ein Unter-Element des LI-Elements trotzem lösen.
              Dieses verstehe ich nicht. Wie verwende ich das? cancelBubble und stopPropagation kommen in der SelfHTML-Doku nicht vor...

              In meiner init-Funktion sind dies die entscheidenden Zeilen:

                
                 lks = (document.all) ? document.all.tree.all.tags("A") :  
                         document.getElementById('tree').getElementsByTagName("A");  
                 for (i=0; i<lks.length; i++ ) {  
                   lks[i].onclick=stp;  
                 }  
              
              

              Das kannst du bestimmt auch serverseitig regeln, wenns das schneller macht, dann brauchst du auch keine Unterscheidung von document.all bzw document.getElementsByTagName, die bei clientseitigen Ansätzen das Ganze für Opera deutlich beschleunigt, denn dann schreibst du ja wahrscheinlich den Eventhandler sowieso direkt als Attribut in jedes Link-Element.

              Die stp-Funktion, die das Weiterreichen des Events an Elternelemente verhindert, ist diese hier:

                
              function stp (e) {  
                if(e) {  
                  e.stopPropagation();  
                } else {  
                  window.event.cancelBubble = true;  
                }  
              }  
              
              

              Gruß Gernot

              1. Lieber Gernot,

                Die stp-Funktion, die das Weiterreichen des Events an Elternelemente verhindert, ist diese hier:

                function stp (e) {
                  if(e) {
                    e.stopPropagation();
                  } else {
                    window.event.cancelBubble = true;
                  }
                }

                Das muss ich mir mor... heute unbedingt reinziehen! Vielen Dank für die Info! Hoffentlich ist das browserübergreifend verfügbar. Muss nämlich meinen Adminbereich auch mit dem IE erreichen können.  
                  
                Liebe Grüße aus Ellwangen,  
                  
                Felix Riesterer.
                
              2. Lieber Gernot,

                function stp (e) {
                  if(e) {
                    e.stopPropagation();
                  } else {
                    window.event.cancelBubble = true;
                  }
                }

                  
                Was wird denn da in "e" übermittelt? Ist "e" ein Bool'scher Wert für ich-bin-der-Internet-Explorer? Laut der [Mozilla-Doku](http://www.mozilla.org/docs/dom/domref/examples.html#998748) wohl nicht; aber dort verstehe ich im Beispiel auch nicht, was da in "e" steht!  
                  
                Im Internet-Explorer braucht es wohl keine Nennung einer Variablen, da anscheinend bei "window.event" vom aktuellen Eventhandler ausgegangen wird...  
                  
                Ist mir alles noch nicht so wirklich klar. Aber ich danke Dir für [Deine Erklärungen](https://forum.selfhtml.org/?t=108819&m=679451) nach wahsagas Ansatz!  
                  
                Liebe Grüße aus Ellwangen,  
                  
                Felix Riesterer.
                
                1. Hallo Felix,

                  Was wird denn da in "e" übermittelt? Ist "e" ein Bool'scher Wert für ich-bin-der-Internet-Explorer? Laut der Mozilla-Doku wohl nicht; aber dort verstehe ich im Beispiel auch nicht, was da in "e" steht!

                  Nun ich reime mir das auch nur zusammen: In "e" (du könntest die Variable auch sonst irgendwie nennen, vollkommen egal) steht eine Referenz auf das Event, wenn die Funktion einen Übergabeparameter erwartet, einen solchen durch den Aufruf aber nicht mitbekommt. Das funktioniert aber nur in Nicht-IEs, IEs haben stattdessen das Objekt window.event.

                  Ist mir alles noch nicht so wirklich klar. Aber ich danke Dir für Deine Erklärungen nach wahsagas Ansatz!

                  Mir eigentlich auch nicht so ganz, ich habe das noch nirgendwo nachgelesen und habe im Moment auch keine Muße dazu. Aber ich denke, ich sollte das mal nachholen. Deshalb wäre ich auch froh, wenn man mich ggf. hier korrigiert. Ich sah bisher immer nur, dass es funktioniert und also habe ich es benutzt ohne mir viele Gedanken zu machen.

                  Welchen Ansatz hast du denn jetzt umgesetzt?

                  Gruß Gernot

                  1. Lieber Gernot,

                    Welchen Ansatz hast du denn jetzt umgesetzt?

                    Wie ich schon geschrieben habe, habe ich das Bubbling ausgehebelt, aber nicht unterdrückt.

                    Nun ich reime mir das auch nur zusammen: In "e" (du könntest die Variable auch sonst irgendwie nennen, vollkommen egal) steht eine Referenz auf das Event, wenn die Funktion einen Übergabeparameter erwartet, einen solchen durch den Aufruf aber nicht mitbekommt. Das funktioniert aber nur in Nicht-IEs, IEs haben stattdessen das Objekt window.event.

                    Also ich habe mir das Beispiel in der Mozilla-Doku nochmal angesehen. Da wird per addEventListener() einer Tabellenzelle (el) ein onClick-Eventhandler aufgedrückt.
                    el.addEventListener("click", l_func, false)
                    Die im Event-Falle aufzurufende Funktion (l_func) empfängt beim Aufruf einen übermittelten Parameter "e". Tja, wo kommt der denn her???

                    Ich vermute, dass der Eventhandler anscheinend automatisch eine Referenz des feuernden Elements übermittelt. Deine Funktion stp(e) prüft ja auf Vorhandensein dieses Parameters, um bei einem Nichtvorhandensein IE-spezifisch zu reagieren. Aber was mache ich in meinem Fall? Mein onclick-Attribut enthält einen Funktionsaufruf mit einem eigenen Parameter! Wie komme ich jetzt an die Referenz des feuernden Elements?

                    Ich werde mal probieren, ob meine Funktionen im Mozilla noch einen zweiten Parameter empfangen. Denn wenn da bei onclick immer so ein "e" übermittelt wird, dann müsste ja bei einer selbst-programmierten Parameterübergabe der Referenzparameter trotzdem ankommen... Und um den Programmierer nicht zu verunsichern wäre es gut, diesen hinten anzustellen. Ich werde das mal ausprobieren.

                    Liebe Grüße aus Ellwangen,

                    Felix Riesterer.

                    1. Lieber Gernot,

                      Ich werde mal probieren, ob meine Funktionen im Mozilla noch einen zweiten Parameter empfangen. Denn wenn da bei onclick immer so ein "e" übermittelt wird, dann müsste ja bei einer selbst-programmierten Parameterübergabe der Referenzparameter trotzdem ankommen... Und um den Programmierer nicht zu verunsichern wäre es gut, diesen hinten anzustellen. Ich werde das mal ausprobieren.

                      ... erfolglos. :-(

                      Meine durch das onclick aufgerufenen Funktionen erhalten nur den Parameter, der auch im Attribut im Funktionsaufruf notiert ist. Das in der Doku übermittelte "e" bleibt mir ein Rätsel. Vielleicht wird das nur bei dynamisch vergebenen Eventhandlern übermittelt? Ich habe nie probiert bei addEventListener einen Funktionsparameter mit einzustellen... Vielleicht kann man das nicht und es wird daher diese Referenz übermittelt?

                      Fragen über Fragen...

                      Liebe Grüße aus Ellwangen,

                      Felix Riesterer.

                      1. Hallo Felix,

                        das hier könnte vielleicht die Lösung für dich sein; habe wild rumprobiert:

                          
                        <html>  
                        <head>  
                        <title>Bubbling verhindern</title>  
                        <meta name="author" content="Gernot Back">  
                        <meta name="generator" content="Ulli Meybohms HTML EDITOR">  
                        <script language="JavaScript">  
                        [code lang=javascript]  
                        function stoppen (e) {  
                          if(window.event)  
                            window.event.cancelBubble=true;  
                          else  
                            e.stopPropagation();  
                        }
                        

                        </script>
                        </head>
                        <body >
                        <p onclick="alert('das kitzelt!')"><a href="#" onclick="stoppen(event)">Event melden</a></p>
                        </body>
                        </html>
                        [/code]

                        Das kitzelt das Elternelement nicht, weil das Bubbling durch die Funktion stoppen(9 blockiert wird.

                        Gruß Gernot

                        1. Lieber Gernot,

                          auch ich habe wild herumprobiert. Als ich den onclick="aufzu(this)" mal mit alert(this.onclick) "ansehen" wollte, da kam im Dialogfenster etwas sehr interessantes:

                            
                          function onclick(event) {  
                          aufzu(this);  
                          }
                          

                          Das bedeutet, dass der Mozilla intern eine Variable "event" in der onclick-Funktion führt, innerhalb derer dann der Code aus dem onclick-Attribut ausgeführt wird. Damit hat man im Eventhandler-Attribut des Mozilla (wahrscheinlich in allen Eventhandlern wie z.B. auch in "mouseover" oder "onchange") immer die Variable "event" zur Verfügung, die eine Referenz des Events enthält.

                          <html>
                          <head>
                          <title>Bubbling verhindern</title>
                          <meta name="author" content="Gernot Back">
                          <meta name="generator" content="Ulli Meybohms HTML EDITOR">
                          <script language="JavaScript">
                          [code lang=javascript]
                          function stoppen (e) {
                            if(window.event)
                              window.event.cancelBubble=true;
                            else
                              e.stopPropagation();
                          }

                          
                          > </script>  
                          > </head>  
                          > <body >  
                          > <p onclick="`alert('das kitzelt!')`{:.language-javascript}"><a href="#" onclick="`stoppen(event)`{:.language-javascript}">Event melden</a></p>  
                          > </body>  
                          > </html>[/code]  
                            
                          In Deinem Beispiel übergibst Du im onclick-Eventhandler einen Funktionsaufruf mit eben obiger Variable "event". In Deiner Funktion taufst Du sie bei Übergabe in "e" um, hast damit die Referenz des Events nun in "e" verfügbar. Damit stimmen unsere Beobachtungen überein und wir haben eine Erklärung gefunden!  
                            
                          Im IE sieht das ja etwas anders aus... Der kennt die windows-Eigenschaft "event", die wiederum eine Bool'sche Eigenschaft "cancelBubble" hat. In windows.event ist wohl gerade das aktuelle Event gespeichert. Auch im IE kann man das onclick-Attribut mit "alert(this);" prüfen. Heraus kommt dann eine Funktion (wie beim Mozilla), die jedoch eine anonyme Funktion ohne übergebenen Parameter ist, und die (auch wie beim Mozilla) den im onclick-Attribut gespeicherten Code ausführt. Damit steht im Eventhandler-Attribut des IE die Variable "event" \_nicht\_ zur Verfügung.  
                            
                          Also wie mache ich das Browser-übergreifend? Wenn ich im onclick-Attribut zum Beispiel notiere "aufzu([wert1, wert2], event);", dann kann ich in der Funktion aufzu() nicht prüfen (andere sind vielleicht schlauer als ich), ob in "event" nun tatsächlich eine Referenz des Events gespeichert ist, da mir auch der IE bei alert(event) ein "object" liefert. Ich habe das ausprobiert. Eine Browserweiche à la `if(event) { mozilla } else { IE }`{:.language-javascript} klappt nicht, da event im IE nicht undefined und nicht false ist. Ein Workaround für den IE wäre sehr umständlich, da ich in \_jedes\_ onclick-Attribut eine Prüfung auf das Vorhandensein von "event" einbauen müsste, um bei Nichtvorhandensein eine Variable "event" mit dem Wert false zu definieren, was den Inhalt des onclick-Attributes im HTML-Code extrem aufbläht (bei etwa 1500 Zeilen Dateibaum!).  
                            
                          => Ich bleibe bei meiner Lösung mit zwei globalen Variablen, bei der das Event Bubbling zwar nicht ausgeschaltet, aber doch effektiv ausgehebelt wird, da ich ansonsten meinen HTML-Quelltext sowas von aufblähen müsste (lange onclick-Attribute), dass die unelegantere Lösung tatsächlich die einfachere ist.  
                            
                          Vielen Dank für Deine Forschungen! Wir haben beide dazugelernt! ;-)  
                            
                          Liebe Grüße aus Ellwangen,  
                            
                          Felix Riesterer.