Linuchs: Click-Event auswerten (stopPropagation)

Moin,

das Thema hattenn wir schon mal. Ich klicke auf ein Objekt (z.B. Adressliste <tr>), um dessen Hintergrund-Farbe zu wechseln. So kann ich in Listen die bearbeiteten Positionen markieren. Dann klicke ich auf einen Link innerhalb dieses Objekts, um zum Bearbeitungsformular (z.B. Adresse) zu kommen.

Nun führt jedoch der Klick auf den Link dazu, dass das selbe Click-Event zum Parent weitergereicht wird. Das soll aber nicht passieren, deshalb mache ich es z.Z. so:

window.addEventListener('DOMContentLoaded', function ( ) {
  // tbody tr Tabellenzeilen per Klick einfaerben ...
  var obj_tbody = document.getElementsByTagName( "tbody" );
  for ( var i=0; i<obj_tbody.length; i++ ) {
    var obj_tr = obj_tbody[i].getElementsByTagName( "tr" );
    for ( var j=0; j<obj_tr.length; j++ ) {
      obj_tr[j].addEventListener('click',  function () { switchMarkierung(this); });
    }
  }
  // ... auch Positionen per Klick einfaerben (muessen nicht tr sein )
  obj = document.getElementsByClassName( "position" );
  for ( i=0; i<obj.length; i++ ) {
    obj[i].addEventListener('click',  function () {
      switchMarkierung(this);
    });
  }
  // Klick auf <a ... nicht wieterreichen
  obj = document.getElementsByTagName( "a" );
  for ( i=0; i<obj.length; i++ ) {
    obj[i].addEventListener('click', function (event) {
      event.stopPropagation();
    });
  }
  // Klick auf <input ... nicht wieterreichen
  obj = document.getElementsByTagName( "input" );
  for ( i=0; i<obj.length; i++ ) {
    obj[i].addEventListener('click', function (event) {
      event.stopPropagation();
    });
  }
});

Das Dumme ist nun, dass es weitere klickbare Objekte gibt, die ich in der Stop-Liste "vergessen" habe, etwa <textarea>.

Ich möchte es umgekehrt machen. Die mit dem EventListener click versehenen Objekte sollen selbst prüfen, ob sie mit dem Klick gemeint sind. Es gab Hinweise von Orlok, dass das gehen soll. Habe aber nicht verstanden, wie das umzusetzen ist.

Linuchs

  1. Hallo Linuchs,

    Ich möchte es umgekehrt machen. Die mit dem EventListener click versehenen Objekte sollen selbst prüfen, ob sie mit dem Klick gemeint sind. Es gab Hinweise von Orlok, dass das gehen soll. Habe aber nicht verstanden, wie das umzusetzen ist.

    Nun ja, das event-Object weiß, welches Element das Ziel des Events war. (target) Target wiederum weiß, wie es heißt, das steckt in seiner Eigenschaft nodeName.

    if (event.target.nodeName == "FOO") {
      // do something
    }
    

    könnte zielführend sein.

    Bis demnächst
    Matthias

    --
    Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
    1. Hallo Matthias,

      if (event.target.nodeName == "FOO") {
        // do something
      }
      

      Ich denke, mit dem nodeName (= tagName?) kann ich nicht wirklich was anfangen.

      Wenn also ein Klickevent zum tr weitergereichtb wird, finde ich den nodeName TR vor und weiss immer noch nicht, ob TR selbst oder ein Child von TR geklickt wurde:

      function switchMarkierung( obj ) {
        alert ( obj.nodeName );
      ...
      }
      window.addEventListener('DOMContentLoaded', function ( ) {
      ...
            obj_tr[j].addEventListener('click',  function () { switchMarkierung(this); });
      ...
      

      Wie also frage ich in switchMarkierung target ab?

      Linuchs

      1. Tach!

        Ich denke, es wäre sehr von Vorteil, dass du dich mal mit den Grundlagen der Eventverarbeitung beschäftigst, anstatt immer von einem Problem auf das nächste zu stoßen.

        Wenn also ein Klickevent zum tr weitergereichtb wird, finde ich den nodeName TR vor und weiss immer noch nicht, ob TR selbst oder ein Child von TR geklickt wurde:

        Der Unterschied ist wo du den Node findest. (Man muss auch nicht den Namen vergleichen, man kann auch die Nodes selbst vergleichen, je nachdem was man erreichen möchte.) Ein Event-Objekt hat jedenfalls zwei Verweise an Bord. Der eine geht zum eigentlichen Auslöser (target), der andere zu dem Node, für den der aktuelle Eventhandler ausgelöst wurde (currentTarget). Für jeden Node in der Event-Bubbling oder -Capturing-Kette wird ja der entsprechende Eventhandler einzeln aufgerufen und jeweils auch ein neues Event-Objekt übergeben. Solange du in diesem Eventhandler bist, zeigt das this auf denselben Node wie auch currentTarget, das target hingegen kann ein anderer Node sein.

        Das heißt konkret, wenn du im Eventhandler deines TRs bist, dann zeigt currentTarget immer auf das TR, das target aber zeigt auf TR, wenn dort geklickt wurden und auf das Child, wenn dort geklickt wurde.

        alert ( obj.nodeName );

        console.log(obj) (ohne nodeName) und die Entwicklertools offenhaben zeigt deutlich mehr interessante Informationen an. alert() kommt in die Mottenkiste.

        dedlfix.

  2. Hallo,

    So kann ich in Listen die bearbeiteten Positionen markieren.

    Warum musst du selber händisch die bearbeitete Position markieren? Ich habe deinen Workflow nicht vor Augen, aber eigentlich sollte die Software sowas von selbst markieren können.

    Gruß
    Kalk

    1. Warum musst du selber händisch die bearbeitete Position markieren? Ich habe deinen Workflow nicht vor Augen, aber eigentlich sollte die Software sowas von selbst markieren können.

      Auf einer gedruckten Liste würde man Positionen abhaken, die erledigt sind. Zum Beispiel optische Kontrolle im Lager / Versand: Position ist vorhanden. Muss deshalb aber nicht unbedingt bearbeitet werden.

      Linuchs

  3. Hallo Linuchs

    Ich möchte es umgekehrt machen. Die mit dem EventListener click versehenen Objekte sollen selbst prüfen, ob sie mit dem Klick gemeint sind. Es gab Hinweise von Orlok, dass das gehen soll. Habe aber nicht verstanden, wie das umzusetzen ist.

    Also, wenn ich dich richtig verstehe, dann hast du eine Reihe von Elementen, für die bei einem Klick eine bestimmte Aktion ausgeführt werden soll. Diese Aktion soll aber nur dann ausgeführt werden, wenn der Klick auf dem jeweiligen Element selbst erfolgt ist, nicht jedoch, wenn auf eines der Kindelemente geklickt wurde.

    <body>
      <ul id="list">
        <li>Das ist normaler Text. <em>Das ist hervorgehobener Text.</em></li>
        <li>Das ist normaler Text. <em>Das ist hervorgehobener Text.</em></li>
        <li>Das ist normaler Text. <em>Das ist hervorgehobener Text.</em></li>
      </ul>
    </body>
    

    Nehmen wir also einmal dieses abstrakte Beispiel einer ungeordneten Liste und stellen uns vor, wir wollten beim Klick auf eines der Listenelemente eine Aktion ausführen. Diese Aktion soll aber nur dann ausgeführt werden, wenn auf das LI-Element selbst geklickt wurde, aber nicht bei einem Klick auf das EM-Element, welches ein Kindelement des Listenelementes ist.

    Um dieses Ziel zu erreichen gibt es nun verschiedene Möglichkeiten. Eine davon könnte so aussehen, dass wir für jedes Listenelement einen Eventlistener registrieren und dann innerhalb der registrierten Handlerfunktion prüfen, ob der Klick auch wirklich auf dem Element erfolgt ist, für das der Handler registriert wurde.

    Dies können wir bewerkstelligen, indem wir den Wert der Eigenschaft target des Eventobjektes, welche das Element referenziert auf das tatsächlich geklickt wurde, mit der Eigenschaft currentTarget des Eventobjektes vergleichen, welche das Element referenziert für das der Handler registriert wurde.

    window.addEventListener('DOMContentLoaded', function ( ) {
      var items = document.getElementById('list').children,
          length = items.length;
      for (var index = 0; index < length; index ++) {
        items[index].addEventListener('click', function (event) {
          var target = event.target;
          if (event.currentTarget === target) {
            console.log(target.tagName);
          }
        });
      }
    });
    

    Wir iterieren hier also über die Kindelemente der Liste und registrieren für jedes der Listenelemente einen Eventhandler. Dieser enthält die bedingte Anweisung, den Namen des Elements in die Konsole zu schreiben, wenn die Eigenschaften target und currentTarget auf dasselbe Objekt verweisen.

    Da wir für jedes Listenelement einen Eventhandler registriert haben, verweist currentTarget hier entsprechend immer auf das jeweilige LI-Element, wohingegen target entweder auf das Listenelement oder auf das EM-Element verweisen kann, eben abhängig davon, wohin tatsächlich geklickt wurde.

    Im Ergebnis wird hier also der Wert der Eigenschaft tagName in die Konsole geschrieben, wenn auf ein Listenelement geklickt wurde und bei einem Klick auf den hervorgehobenen Text passiert nichts, denn in diesem Fall würde die Eigenschaft target auf das EM-Element verweisen, wohingegen die Eigenschaft currentTarget das LI-Element referenziert. Der durchgeführte Vergleich würde bei einem Klick auf den hervorgehobenen Text also negativ ausfallen. Die Bedingung wäre nicht erfüllt.

    Das wäre also im Prinzip genau das, was wir wollen, nämlich dass Klicks auf Kindelemente ignoriert werden und die jeweilige Aktion nur dann ausgeführt wird, wenn auf das Element geklickt wurde, für das der Eventhandler registriert wurde. – Aber besonders elegant wäre das nicht.

    window.addEventListener('DOMContentLoaded', function ( ) {
      var list = document.getElementById('list');
      list.addEventListener('click', function (event) {
        var target = event.target;
        if (target.tagName === 'LI') {
          console.log('bingo');
        }
      });
    });
    

    Statt für jedes einzelne Listenelement einen Eventhandler zu registrieren können wir nämlich auch einen Handler für das gemeinsame Elternelement registrieren, also für die Liste selbst. In diesem Fall hilft uns die Eigenschaft currentTarget natürlich nicht weiter, da diese hier nun immer auf die Liste verweisen würde, und nicht mehr auf die Listenelemente.

    Aber da wir wissen, dass der Wert der Eigenschaft tagName bei einem LI-Element immer der String LI ist und wir zudem wissen, dass von target immer das Element referenziert wird, bei dem das Ereignis tatsächlich eingetreten ist, können wir entsprechend prüfen, ob auf ein LI-Element geklickt wurde, indem wir den Wert der Eigenschaft tagName mit dem String LI vergleichen.

    Wir erreichen hier also ebenfalls unser Ziel, dass die Aktion nur dann ausgeführt wird, wenn auf ein Listenelement geklickt wurde, nicht jedoch bei Klicks auf irgendwelche Kindelemente.

    Der Schlüssel für eine effiziente Ereignisbehandlung mittels Event Delegation liegt also in dem Wissen um die Eigenschaft target des Eventobjektes, nämlich dass diese grundsätzlich auf das Element verweist, bei dem das Ereignis tatsächlich eingetreten ist, und in dem Wissen, dass die meisten Ereignisse innerhalb des DOM vom Zielelement aus aufsteigen, sodass Eventhandler bei Elternelementen des über die Eigenschaft target referenzierten Elementes ebenfalls ausgelöst werden.

    Es kann also ein einzelner Eventhandler bei einem Element registriert werden, der immer auch dann aufgerufen wird, wenn das entsprechende Ereignis innerhalb des Teilbaums der Kindelemente aufgetreten ist, und es kann anhand der Eigenschaften der Elemente dann in der Handlerfunktion selektiert werden.

    Dabei kann man wie in dem Beispiel hier prüfen, ob das Zielelement, also der Wert von target einem bestimmten Elementtyp angehört, indem man den Wert der Eigenschaft tagName oder den Wert der Eigenschaft nodeName mit dem jeweils passenden String vergleicht.

    Man könnte auch prüfen, ob die id oder der Wert von className des Zielelementes dem Wert des Elementes entspricht, für das eine Aktion durchgeführt werden soll.

    Auch könnte man die Ausführung von Anweisungen davon abhängig machen, ob ein Element ein direktes Kindelement eines anderen Elementes ist, indem man die Eigenschaft parentElement des Zielelementes untersucht. Oder man verwendet eines oder mehrere der tausend anderen Merkmale, die es ermöglichen dasjenige Element, beziehungsweise diejenigen Elemente zu identifizieren, für welche die Aktion ausgeführt werden soll.

    • Also statt eine Unzahl an Eventhandlern zu registrieren und irgendwie umständlich mit Methoden wie stopPropagation zu hantieren, solltest du dir das Leben leicht machen und nur einen einzigen Handler auf einem gemeinsamen Elternelement registrieren.

    • Dieser Handler fängt dann alle Klicks ab, die auf dem Element selbst oder auf irgendeinem Element erfolgt sind, das in direkter Linie von dem Element abstammt, auf dem der Handler registriert wurde.

    • Innerhalb der Handlerfunktion referenzierst du dann über event.target das Element, bei dem das Ereignis tatsächlich eingetreten ist. Also das Element auf das tatsächlich geklickt wurde.

    • Dann prüfst du, ob dieses Element, bei dem das Ereignis eingetreten ist, bestimmte Kriterien erfüllt, also ob es einem bestimmten Elementtyp oder einer Klasse angehört, ob es selbst Kindelemente hat oder es das Kind eines bestimmten Elternelementes ist, usw. usw.

    • Für den Fall, dass der Klick auf einem Element erfolgt ist, das den von dir aufgestellten Kriterien entspricht, führst du dann deine Aktion aus. Sonst nicht.

    Gruß,

    Orlok

    1. Hallo Orlok,

      Ich fühle mich bestätigt :-)

      Bis demnächst
      Matthias

      --
      Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
    2. Hallo,

        var items = document.getElementById('list').children,
      

      nur ein kleiner unwichtiger Einwand, und auch nur, weil ich mit „Kindknoten“ schon mal Probleme hatte:

      Kinder des UL sind nicht nur die LI sondern auch die aus den White Spaces bestehenden Textknoten zwischen </li> und <li>. Die würden in diesem Beispiel auch erfasst. Sonst +1.

      Gruß
      Jürgen

      1. Hallo Jürgen

          var items = document.getElementById('list').children,
        

        nur ein kleiner unwichtiger Einwand, und auch nur, weil ich mit „Kindknoten“ schon mal Probleme hatte:

        Kinder des UL sind nicht nur die LI sondern auch die aus den White Spaces bestehenden Textknoten zwischen </li> und <li>. Die würden in diesem Beispiel auch erfasst.

        Nö. Genau deswegen habe ich ja children verwendet und nicht childNodes. ;-)

        <body>
          <ul id="list">
            <li>Text <em>Emphasized</em></li>
            <li>Text <em>Emphasized</em></li>
          </ul>
        </body>
        

        Wenn wir hier nun die Eigenschaft childNodes verwenden, dann sähe das tatsächlich so aus, dass nicht nur die Elementknoten berücksichtigt werden:

        const nodes = Array.from(document.getElementById('list').childNodes);
        
        console.log(nodes.every(item => item.nodeType === 1)); // false
        

        Die von der Eigenschaft children zurückgegebene HTMLCollection enthält im Gegensatz dazu aber tatsächlich nur diejenigen Kindknoten, bei denen es sich um Elemente handelt.

        const nodes = Array.from(document.getElementById('list').children);
        
        console.log(nodes.every(item => item.nodeType === 1)); // true
        

        Wenn man also alle Kindelemente haben möchte, ist entsprechend children zu verwenden.

        console.log(nodes); // Array [ <li>, <li> ]
        

        Gruß,

        Orlok

        1. Hallo,

          Nö. Genau deswegen habe ich ja children verwendet und nicht childNodes. ;-)

          kleiner aber feiner Unterschied, den ich noch nicht kannte. querySelectorAll("#list > li") wäre da ja auch noch möglich, weist du was performanter ist?

          Gruß
          Jürgen

          1. Hi,

            Nö. Genau deswegen habe ich ja children verwendet und nicht childNodes. ;-)

            kleiner aber feiner Unterschied, den ich noch nicht kannte. querySelectorAll("#list > li") wäre da ja auch noch möglich, weist du was performanter ist?

            ich weiß es nicht, aber ich habe die starke Vermutung, dass die Verwendung der "von Haus aus" existierenden Collections günstiger ist als eine generische Lösung, die das DOM anhand eines beliebigen Selektors absuchen muss.

            So long,
             Martin

            --
            Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
            - Douglas Adams, The Hitchhiker's Guide To The Galaxy
            1. @@Der Martin

              kleiner aber feiner Unterschied, den ich noch nicht kannte. querySelectorAll("#list > li") wäre da ja auch noch möglich, weist du was performanter ist?

              ich weiß es nicht, aber ich habe die starke Vermutung, dass die Verwendung der "von Haus aus" existierenden Collections günstiger ist als eine generische Lösung, die das DOM anhand eines beliebigen Selektors absuchen muss.

              querySelector()/querySelectorAll() lässt sich übrigens nicht nur auf document anwenden, sondern auch auf HTMLElemente. Wenn man list also bereits hat, geht

              var items = list.querySelectorAll(':scope > li');
              

              und man würde nicht das ganze DOM erneut durchsuchen, sondern nur den Teilbaum unter list.

              Aber natürlich kann (sollte!) man sich auch das sparen, wenn die children-Collection bereits „von Haus aus“ existiert.

              LLAP 🖖

              --
              “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
              Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
              1. Hallo Gunnar,

                var items = list.querySelectorAll(':scope > li');
                

                das würde mir doch nur die LIs liefern, die direkte Kinder von „list“ sind, wohingegen

                var items = list.querySelectorAll('li');
                

                oder

                var items = list.querySelectorAll(':scope li');
                

                mir doch alle LIs, auch die in Unterlisten, liefern müsste.

                In meinem GPX-Parser (im Wesentlichen aus 2009) habe ich das Problem, das ich nur Unterelemente suche, die direkte Kinder sind. Zurzeit suche ich mit getElementsByTagname und prüfe dann die Elternknoten der gefundenen Elemente.

                Gruß
                Jürgen

              2. Hallo,

                var items = list.querySelectorAll(':scope > li');
                

                ich habe da etwas mit rumexperimentiert und musste mit Schrecken feststellen, das kein MS-Browser, also weder IE noch Edge, „:scope“ kennen. Sie werfen einen Syntaxterror.

                Gruß
                Jürgen

    3. Statt für jedes einzelne Listenelement einen Eventhandler zu registrieren können wir nämlich auch einen Handler für das gemeinsame Elternelement registrieren, also für die Liste selbst.

      Ich denke, meine Denkblockade war das Wort target = ZIEL, während ich nach der QUELLE gesucht habe, an der ein Klick ausgelöst wurde.

      Habe ich nun sinngemäß gestestet für tbody:

      window.addEventListener('DOMContentLoaded', function ( ) {
        var obj_tbody = document.getElementsByTagName( "tbody" );
        for ( var i=0; i<obj_tbody.length; i++ ) {
          obj_tbody[i].addEventListener('click', function (event) {
            var target = event.target;
            alert( "target=[" +target.tagName +"] currentTarget=[" +event.currentTarget.tagName +"]" );
          });
        }
      ...
      

      Alert zeigt z.B.

      target=[SMALL] currentTarget=[TBODY]
      

      Damit ist mir das Verfahren verständlich. Mich interessiert jedoch die Zeile TR, die ich farbig markieren möchte. Also kann ich das Klick-Event doch nicht so hoch in der Hirarchie ansetzen, sondern für jedes einzelne TR wie bisher?

      Aber nehmen wir an, ich möchte das geklickte SMALL rot einfärben. Ah ja:

      target.style.color = "#f00";
      

      Linuchs

      1. Hallo

        target=[SMALL] currentTarget=[TBODY]
        

        Damit ist mir das Verfahren verständlich. Mich interessiert jedoch die Zeile TR, die ich farbig markieren möchte. Also kann ich das Klick-Event doch nicht so hoch in der Hirarchie ansetzen, sondern für jedes einzelne TR wie bisher?

        Doch das geht. Da du, wenn ich dein SMALL sehe, das ja selbst nicht Kind von TR sein kann, den Abstand des geklickten Elements von deiner TR nicht kennst, kannst du z.B., wie auf dieser Seite gezeigt, das Elternelement de geklickten Elements prüfen, bis du auf das TR stößt. Das Stichwort parentElement hat Orlok ja bereits gegeben.

        Tschö, Auge

        --
        Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
        Wolfgang Schneidewind *prust*
      2. Hallo Linuchs,

        Ich denke, meine Denkblockade war das Wort target = ZIEL, während ich nach der QUELLE gesucht habe, an der ein Klick ausgelöst wurde.

        Das ist tatsächlich gar nicht mal so selten.

        Von welchem Element wurde das Ereignis ausgelöst = Was ist die Quelle des Ergeignisses.

        Beachte aber:

        Ein Element kann kein Event auslösen, es kann höchstens Ziel eines Events sein.

        Beispiel Click:
        Das Element kann nicht klicken, es kann höchstens Ziel eines Klicks sein.

        Bis demnächst
        Matthias

        --
        Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
        1. Hallo,

          Ich denke, meine Denkblockade war das Wort target = ZIEL, während ich nach der QUELLE gesucht habe, an der ein Klick ausgelöst wurde.

          ja, diese auch für mein Empfinden verkehrte Benamsung verwirrt mich auch immer wieder.

          Von welchem Element wurde das Ereignis ausgelöst = Was ist die Quelle des Ergeignisses.

          Genau.

          Beachte aber:

          Ein Element kann kein Event auslösen, es kann höchstens Ziel eines Events sein.

          Beispiel Click:
          Das Element kann nicht klicken, es kann höchstens Ziel eines Klicks sein.

          Okay, das ist die Betrachtung aus Nutzersicht. Aus Programmierersicht ist aber das geklickte Element dasjenige, das als Reaktion auf das Ereignis ein event-Objekt auf die Reise schickt, es ist also Quelle des event-Objekts (nicht des Ereignisses).

          Ciao,
           Martin

          --
          Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
          - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    4. Hallo Orlok,

      ich denke, deine Erklärungen sind so umfangreich, dass der wahre Kern nicht immer gleich sichtbar wird, wie bei versteckten Ostereiern. Ich mache jetzt dieses und es scheint das zu sein, was ich gesucht habe:

      /* *************************************************************************
       * 
       * ein Klick-Event fuer die ganze Seite. Wenn Klick, dann enthaelt
       *
       * target: Zeiger auf das Objekt, auf das geklickt wurde, z.B. <input ...
       * currentTarget: Zeiger auf Objekt des Klick-Events, hier also <body>
       * 
       * ************************************************************************* */
      window.addEventListener('DOMContentLoaded', function ( ) {
        document.getElementsByTagName( "body" )[0].addEventListener('click', function (event) {
          var obj = event.target;
      //  alert( "target=[" +obj.tagName +"] target.parent=[" +obj.parentElement.tagName +"]" );
          if ( obj.tagName == "TD" ) obj = obj.parentElement; // wenn auf eine freie Stelle im TD geklickt, dann nimm TR
          if ( obj.tagName == 'TR' || obj.classList.contains( "position" )) {
            switchMarkierung( obj );
          }
        });
      });
      

      Der Code ist so überraschend schlank, ich stelle meine alte Version noch mal dagegen, die aber nicht richtig funktionierte:

      window.addEventListener('DOMContentLoaded', function ( ) {
        // tbody tr Tabellenzeilen per Klick einfaerben ...
        var obj_tbody = document.getElementsByTagName( "tbody" );
        for ( var i=0; i<obj_tbody.length; i++ ) {
          var obj_tr = obj_tbody[i].getElementsByTagName( "tr" );
          for ( var j=0; j<obj_tr.length; j++ ) {
            obj_tr[j].addEventListener('click',  function () { switchMarkierung(this); });
          }
        }
        // ... auch Positionen per Klick einfaerben (muessen nicht tr sein )
        obj = document.getElementsByClassName( "position" );
        for ( i=0; i<obj.length; i++ ) {
          obj[i].addEventListener('click',  function () {
            switchMarkierung(this);
          });
        }
        // Klick auf <a ... nicht wieterreichen
        obj = document.getElementsByTagName( "a" );
        for ( i=0; i<obj.length; i++ ) {
          obj[i].addEventListener('click', function (event) {
            event.stopPropagation();
          });
        }
        // Klick auf <input ... nicht wieterreichen
        obj = document.getElementsByTagName( "input" );
        for ( i=0; i<obj.length; i++ ) {
          obj[i].addEventListener('click', function (event) {
            event.stopPropagation();
          });
        }
      });
      

      Danke dir für deine Mühe, hat bei mir endlich den AHA Effekt ausgelöst.

      Linuchs