Linuchs: onclick-Event abfangen

Hallo,

in HTML-Tabellen kann ich Zeilen durch Klick farbig markieren / ent-färben:

<tr onclick="switchMarkierung(this)">

Die Zeilen enthalten auch Links. Wenn ich auf einen Link klicke, feuert der onclick der Zeile auch. Wie kann ich das verhindern?

Linuchs

  1. Hallo Linuchs

    function switchMarkierung (e) {
    
      if (e.target.tagName !== 'TR') {
    
        return;
    
      }
    
      // ...
    
    }
    

    Mal das versucht?

    PS: Würde empfehlen, statt onclick die addEventListener-Methode zu verwenden.

    Beste Grüße,

    var

  2. @Linuchs

    Übrigens, ich kenne ja den Kontext nicht, aber wenn es dir nur darum geht, die aktuell angeklickte Zeile zu markieren, könntest du die Markierung auch mit CSS wechseln, indem du die TR über die Pseudoklassen active und focus ansprichst.

    Gruß,

    var

    1. Hallo var,

      danke für die Antwort. Aber wenn ich ein Element in einer Zeile anklicke, ist damit ja auch die Zeile selbst angeklickt.

      Ich vermute, dass das onklick-Event zuerst auf das Element angewendet und dann an die übergeordnete Zeile weitergereicht wird - bis hin zur body oder html Ebene. Also muss dieses event bubbling unterbrochen werden.

      Die Abfrage, ob "tr" angeklickt wurde, ist immer wahr, hilft mir also nicht. Hier mal auf das Wesentliche eingedampft:

      <script>
      function machGruen( obj ) {
        obj.style.background = "#0f0";
      }
      </script>
      <p onclick="machGruen(this)">Ich möchte nur dieses <b onclick="machGruen(this)">Wort</b>, aber nicht die ganze Zeile grün machen.</p>
      

      Linuchs

      1. Hier das Beispiel aus der Praxis. Es zeigt, dass mehrere onclick-Events in der Zeile vorkommen:

        <script>
        function machGruen( obj ) {
          obj.style.background = "#0f0";
        }
        </script>
        
        <tr onclick="machGruen(this)" class=bghgrau>
        <td><a href='javascript:zeigAdressformular(0,0,13437)'>3</a></td>
        <td title='kurzname=133'>50Hertz Transmission GmbH <b>200+/100</b></td>
        <td>Berlin</td>
        <td>Rödel, Andreas</td>
        <td class='courier'>.....</td>
        <td onClick="makeAnc(this,'p136',13437)">*</td>
        <td class='courier' onClick="makeAnc(this,'p103',13437)" class=>V12 30</td>
        <td></td>
        <td onClick="makeAnc(this,'p131',13437)" class=bgrot>0-0</td>
        <td onClick="makeAnc(this,'p134',13437)" class='bggruen'>6-6</td>
        <td onClick="makeAnc(this,'p132',13437)">T-Plan</td>
        </tr>
        
        1. Problem nicht "gelöst", aber umgangen, damit kann ich erstmal leben:

          <script>
          function machGruen( obj ) {
            obj.style.background = "#0f0";
            return false;
          }
          </script>
          <p ondblclick="machGruen(this)">Doppelklick in die Zeile macht die Zeile grün, Einfach-Klick auf den <a href="http://forum.selfhtml.org/self">Link</a> aber nicht.</p>
          
          
          1. Hallo,

            <p ondblclick="machGruen(this)">Doppelklick in die Zeile macht die Zeile grün, Einfach-Klick auf den <a href="http://forum.selfhtml.org/self">Link</a> aber nicht.</p>
            
            

            keine gute Idee. Gar keine gute Idee.

            Bedenke, dass von zwei schnell aufeinanderfolgenden Klicks immer der erste als Einfachklick an die Anwendung signalisiert wird, und erst der zweite als Doppelklick. Anders gesagt: Der Doppelklick-Aktion geht immer die Einzelklick-Aktion voraus. In deinem Fall würde das heißen, dass dem Link gefolgt wird, und in der Zeit, bis die Zielseite geladen wird, könnte eventuell noch die Doppelklick-Aktion, also das Umfärben erfolgen. Das Resultat ist dann aber durch die neu geladene Seite schnell wieder weg.

            Besser: Das Event nach Gebrauch entsorgen.

            So long,
             Martin

          2. @Linuchs

            Wie Der Martin schon erläutert hat, ist das keine gute Idee und du solltest hier wirklich Alternativen in Betracht ziehen!

            So wie ich das sehe, kannst du auf JavaScript komplett verzichten, wenn es nur darum geht, CSS-Eigenschaften zu verändern, entweder wie in diesem Post von mir Angedeutet mit Pseudoklassen als Selektoren, oder aber, sofern das nicht reicht und du Styles dauerhaft verändern willst, indem du dich eines TricksTricks bedienst, mit CSS-Animation und animation-fill-mode: forwards.

            Im Gegensatz zu dem verlinkten Beispiel von mir könntest du die "Animation" von 0.1s auch als Klasse definieren und so mehreren Elementen zugänglich machen.

            Aber selbst, wenn du das unbedingt über Javascript machen willst, solltest du ernsthaft darüber nachdenken, ob es so eine gute Sache ist, dein Markup mit onclick-Handlern vollzustopfen! Wenn du dir dein eigenes Beispiel aus der Praxis ansiehst, wirst du feststellen, wie unübersichtlich dein Code ist, und dass du dadurch einige Flüchtigkeitsfehler eingebaut hast: Mal einfache, mal doppelte Anführungszeichen, mal gar keine, eimal class=>...

            Es wäre meiner Ansicht nach echt besser, wenn du HTML und JavaScript trennen würdest, und wie in meinem Eingangspost vorgeschlagen, die addEventListener-Methode verwenden würdest, - und am elegantesten, wenn du dir das Event-Bubbling nutzbar machen und deine Event-Behandlung wie hier vorgeschlagen zentralisieren würdest. - Die Elemente selektieren kannst du mit den hier im Wiki dokumentierten Methoden.

            Aber wie gesagt, das wären nur meine Empfehlungen! ;-)

            Gruß,

            var.

        2. @Linuchs

          Mir ist noch nicht so ganz klar, was du erreichen willst.

          Willst du, dass die td beim anklicken dauerhaft die Farbe wechseln, oder nur solange, wie die Maustaste gedrückt bzw. der Cursor über dem Element ist?

          Sollte es das sein, kannst du zum Beispiel jedes 6. td mit

          td:nth-child(6):active, td:nth-child(6):focus, td:nth-child(6):hover {
          
            background-color: rgb(50, 255, 50);
          
          }
          

          selektieren --> live-Beispiel --> Wiki

          Wenn du die Farbe hingegen dauerhaft ändern willst, bleibt AFAIK nur JavaScript, aber da kannst du, wie ich in meinem ersten Post schrieb, mit e.target das richtige Element selektieren.

          Gruß,

          var

      2. Hallo,

        Ich vermute, dass das onklick-Event zuerst auf das Element angewendet und dann an die übergeordnete Zeile weitergereicht wird - bis hin zur body oder html Ebene. Also muss dieses event bubbling unterbrochen werden.

        Korrekt, und das kann man mit 'stopPropagation()' erreichen (Ausschnitt):

        <p onclick="machGruen(this)">Ich möchte nur dieses <b onclick="event.stopPropagation();machGruen(this)">Wort</b>, aber nicht die ganze Zeile grün machen.</p>
        

        Gruss, Worf

        1. Qapla'

          Ja, man kann das Event-Bubbling unterbrechen, aber man könnte es sich auch zu Nutze machen.

          Unter der Voraussetzung, dass CSS-Eigenschaften dauerhaft geändert werden sollen (was aus Linuchs Beiträgen nicht so ganz klar hervorging) und eine JavaScript-Lösung her muss(?), könnte man statt das HTML mit onclick zuzupflastern auch gleich die entsprechenden Events an einer zentralen Stelle abfangen und entsprechend verarbeiten:

          var body = document.getElementsByTagName('BODY')[0];
          
          body.addEventListener('click', function (e) {
          
            switch (e.target) {
          
              case //...
          
            }
          
          });
          

          Nur so eine Idee...

          Gruß,

          var

  3. @@Linuchs

    <tr onclick="switchMarkierung(this)">

    switchMarkierung ist grässliches Denglisch. Und Umschalten heißt üblicherweise toggle, sodass toggleMark oder toggleSelect sinnvolle Funktionsbezeichner wären.

    Und JavaScript-Code gehört nicht in HTML-Attribute.

    Die Zeilen enthalten auch Links. Wenn ich auf einen Link klicke, feuert der onclick der Zeile auch. Wie kann ich das verhindern?

    Wie Worf sagte.

    LLAP 🖖

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)