AndyNail: ondblclick löst auch die onclick Funktionen aus

Hallo zusammen,

auf meiner Seite soll ein Click Funktionen Starten und der Doppelclick andere Funktionen starten:

<div style='float:left; width:40px; height:40px'><a name='SubButton' id='SubButton$ID' class='SubButtons' href='#' onclick='ShowSubLinks($ID); this.blur();' ondblclick='SaveOnList($ID);'><img style='background:transparent; width:30px; height:30px; margin-left:5px; margin-top:5px' src='Pictures/SubUp.png'/></a></div>

Ich entnahm mal das return false aus dem Netz, mit der Hoffnung das nix weiteres passiert. Doch wohl egal ob ich einmal oder zweimal draufklicke. Der Code des onclick wird immer ausgeführt und beim Doppelclick wohl dann auch dieser.

Also wie bekomme ich das bitte hin das es sich nur bei den Ereignissen/Funktionen unterscheidet, je nach dem wie oft ich darauf geclickt habe, aber dann auch nur der zugewiesene Code ausgeführt wird?

Dann schonmal vielen Dank für jede Mühe und ich freue mich auf positive Ergebnisse.

Gruß AndyNail

  1. Hallo,

    Doch wohl egal ob ich einmal oder zweimal draufklicke. Der Code des onclick wird immer ausgeführt und beim Doppelclick wohl dann auch dieser.

    ja, das ist auch absolut logisch: Erst erfolgt mal ein Klick, der entsprechend gemeldet und behandelt wird. Kurze Zeit später gibt's einen zweiten Klick, und erst dann "weiß" das System wegen des geringen zeitlichen Abstands, dass es sich um einen Doppelklick handeln soll.

    Also wie bekomme ich das bitte hin das es sich nur bei den Ereignissen/Funktionen unterscheidet, je nach dem wie oft ich darauf geclickt habe, aber dann auch nur der zugewiesene Code ausgeführt wird?

    Die "gute" Methode: Wähle die Einfachklick-Aktion so, dass sie zur Doppelklick-Aktion passt. Nimm dir ein Beispiel an fast allen GUIs. Da selektiert der erste Klick zum Beispiel das angeklickte Element, und der zweite (der Doppelklick) öffnet es.

    Die weniger gute Methode: Verzögere die Einfachklick-Aktion eine kurze Zeit. Kommt innerhalb dieser kurzen Wartezeit die Doppelklick-Meldung, ignoriere den bereits registrierten Einzelklick. Schön ist das nicht, weil eben auch die Reaktion auf einen gezielten Einzelklick dann verzögert kommt.

    So long,
     Martin

    1. Moin!

      Die "gute" Methode: Wähle die Einfachklick-Aktion so, dass sie zur Doppelklick-Aktion passt. Nimm dir ein Beispiel an fast allen GUIs. Da selektiert der erste Klick zum Beispiel das angeklickte Element, und der zweite (der Doppelklick) öffnet es.

      So und nur so.

      Die weniger gute Methode: Verzögere die Einfachklick-Aktion eine kurze Zeit. Kommt innerhalb dieser kurzen Wartezeit die Doppelklick-Meldung, ignoriere den bereits registrierten Einzelklick. Schön ist das nicht, weil eben auch die Reaktion auf einen gezielten Einzelklick dann verzögert kommt.

      Dagegen spricht, dass die maximale Dauer des Doppelklicks (normal ca. 250ms = 1/4 Sekunde) von einigen Benutzern mit motorischen Störungen stark verlängert (oft auf 500ms = 1/2 s) wird. Wöllte man das berücksichtigen, dann hätte man bei einer so langen Verzögerung das Problem, dass der Einfachklick von denen mit der Normaleinstellung wegen des vermeintlichen Nichtfunktionierens (Es tut sich ja nichts ...) wiederholt wird. Was dann als nicht beabsichtigter Doppelklick gewertet wird.

      Das geht also nicht. Es bleibt nur obiges.

      Denktopanwendungen müssen in 1/10 Sekunde in irgendeiner Form reagieren. Webanwendungen eigentlich auch. Und sei es, dass ein "Bitte warten Sie" erscheint.

      Jörg Reinholz

  2. Hallo AndyNail,

    Dass das Verhalten der Spezifikation entspricht, haben meine Vorredner ja schon klargestellt.

    Als Alternative kannst du auch andere Maustasten abfragen. Da hast du jedoch ein Problem mit Nutzern ohne Maus.

    Optimal fände ich nicht irgendeine (versteckte) Doppelklickfunktion, sondern ein ordentlich beschriftetes Icon oder einen Text.

    Dein HTML ist auch nicht optimal.

    • Verwende keine inline-CSS-Angaben.
    • Benutze keine on-Attribute.
    • Ein a-Element scheint möglicherweise die falsche Wahl zu sein. Du kannst auch einfach das href weglassen, dann brauchst du auch kein return: false.
    • Es sieht für mich so aus, als bautest du einen Button nach. Verwende das button-Element.

    Bis demnächst
    Matthias

    --
    Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
    1. @@Matthias Apsel

      • Ein a-Element scheint möglicherweise die falsche Wahl zu sein. Du kannst auch einfach das href weglassen

      Nein, nicht einfach so.

      dann brauchst du auch kein return: false.

      Aber dafür brauchst du dann tabindex="0", damit das a-Element ohne href-Attribut überhaupt per Tastatur anwählbar ist. Außerdem brauchst du role="button".

      • Es sieht für mich so aus, als bautest du einen Button nach. Verwende das button-Element.

      Das allerdings. Steve Faulkners erste Regel zur Verwendung von ARIA: Verwende nicht ARIA.

      LLAP 🖖

      --
      „Wir haben deinen numidischen Schreiber aufgegriffen, o Syndicus.“
      „Hat auf dem Forum herumgelungert …“
      (Wachen in Asterix 36: Der Papyrus des Cäsar)
    2. OK dann wieder Hallo,

      es ist aber auch so das nix funktioniert. Ich brauche doch wohol das href um ein Link so anzeigen zu können, was Designtechnisch zu den Links daneben passen soll. Und wenn ich auf das <div> Element einen click mache springt mir die Anzeige der gesamten Liste stets nach oben, was dann beim klicken auf den Link nicht passirt.

      OK ich habe ich Buttons in der Liste und werde die Funktion wohl auf den Button setzen, auf diesem aber bereits eine Funktion zur Verfügung stehen muss. Und so dachte ich es erst einmal mit diesem Button zu testen, womit ich aber keinen Erfolg erzielen konnte, da es so aussieht als müsse die Einmal-Klick-Funktion unbedingt ausgeführt werden:

      echo "<div style='float:left; width:40px; height:40px; margin-right:5px'><a name='SubButton' id='SubButton$ID' onclick='this.blur()' href=\"javascript: ShowSubLinks($ID)\" style='padding:5px'><div style='background-image:url(Pictures/SubUp.png); width:30px; height:30px; '></div></a></div>";
      
      function ShowThisSubLinks(ID)
      {
      	if (document.getElementById('SubList'+ID).style.display == "none")
      	{
      	document.getElementById('SubList'+ID).style.display = ""	
      	document.getElementById('SubButton'+ID).getElementsByTagName('IMG')[0].src = "Pictures/SubUp.png"
      	document.getElementById('SubButton'+ID).setAttribute("View", "2")
      	}
      }
      function HideThisSubLinks(ID)
      {
      	if (document.getElementById('SubList'+ID).style.display != "none")
      	{
      	document.getElementById('SubList'+ID).style.display = "none"
      	document.getElementById('SubButton'+ID).getElementsByTagName('IMG')[0].src = "Pictures/SubDown.png"
      	document.getElementById('SubButton'+ID).setAttribute("View", "1")
      	}
      }
      

      Also was dann jetzt, was mit onclick ja auch nicht gepasst hatte? Und dabei laden wir uns ja die Seitten herunter und dann sollte doch auch bloß die Siete mit den Funktionen umgehen könennen. Was ich aber nicht hinbekommen will und ich auch glaube es auch schon mit onclick in dem Link probiert hatte.

      Also wie dann jetzt weiter ? Es kann ja auch so sein, doch gebe es nicht vielleicht Trick17 um so etwas erreichen zu können? Und so möchte ich mich bereits jetzt für alle Infos bei Euch bedanken.

      Danke Gruß AndyNail

      1. Hallo AndyNail,

        es ist aber auch so das nix funktioniert. Ich brauche doch wohol das href um ein Link so anzeigen zu können, was Designtechnisch zu den Links daneben passen soll.

        Verwende nicht die Elemente, die designtechnisch passen, sondern die, die semantisch passen. Ein Link führt auf eine andere Seite oder eine andere Stelle innerhalb derselben Seite. Das soll bei dir gerade eben nicht passieren. Deshalb ist a die falsche und button die richtige Wahl. Oder um es etwas weniger streng klingen zu lassen, die schlechtere resp. bessere Wahl

        Und wenn ich auf das <div> Element einen click mache springt mir die Anzeige der gesamten Liste stets nach oben, was dann beim klicken auf den Link nicht passirt.

        Ja. href=# springt zum Seitenanfang. Deshalb das return: false. Warum das Springen jetzt beim Div passiert, erschließt sich mir nicht. href=javascript: ist imho auch nicht besser als onclick. Schau dir das Eventhandling an. Für den Anfang https://wiki.selfhtml.org/wiki/AddEventListener

        Bis demnächst
        Matthias

        --
        Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
      2. @@AndyNail

        echo "<div style='float:left; width:40px; height:40px; margin-right:5px'><a name='SubButton' id='SubButton$ID' onclick='this.blur()' href=\"javascript: ShowSubLinks($ID)\" style='padding:5px'><div style='background-image:url(Pictures/SubUp.png); width:30px; height:30px; '></div></a></div>";
        

        Es ist i.a.R. keine gute Idee, Markup mit PHP echo auszugeben. Besser die Daten mit PHP ins Markup schreiben:

        <div style='float:left; width:40px; height:40px; margin-right:5px'>
          <a name='SubButton' id='SubButton<?= $ID ?>' onclick='this.blur()' href="javascript: ShowSubLinks(<?= $ID ?>)" style='padding:5px'>
            <div style='background-image:url(Pictures/SubUp.png); width:30px; height:30px;'></div>
          </a>
        </div>
        

        Style-Angaben gehören nichts ins Markup (style-Attribute), sondern ins Stylesheet.

        Was soll das onclick='this.blur() bewirken? Den Focus vom gerade angeclickten Element wegzunehmen ist wohl keine so gute Idee.

        a-Elemente dienen zur Verlinkung auf andere Ressourcen (bzw. Sprungmarken). Zur Ausführung von Aktionen auf einer Seite ist – wie schon gesagt – button zu verwenden. (Buttons können so gestylet werden, dass sie keinen Rahmen und keine Hintergrundfarbe haben und genauso wie Links aussehen.)

        Bei dir gibt es keinerlei Inhalt; selbst das innere div ist leer. Das Icon SubUp.png ist keine Verzierung, sondern Inhalt; das gehört demzufolge in ein img-Element (bzw. svg) – mit Alternativtext, der erscheint, wenn das Bild nicht geladen werden kann, bzw. der Nutzern von Screenreadern vorgelesen wird.

        Das Markup sähe also so aus:

        <button onclick="ShowSubLinks(<?= $ID ?>);">
          <img src="Pictures/SubUp.png" alt="Untermenü anzeigen"/>
        </button>
        

        Die Darstellungsangaben dazu wie gesagt im Stylesheet.

        Noch schicker wäre freilich, auch den JavaScript-Code nicht ins Markup (onclick-Attribut) zu schreiben, sondern Event-Handler per JavaScript zu definieren.


        function ShowThisSubLinks(ID)
        {
        	if (document.getElementById('SubList'+ID).style.display == "none")
        	{
        	document.getElementById('SubList'+ID).style.display = ""	
        	document.getElementById('SubButton'+ID).getElementsByTagName('IMG')[0].src = "Pictures/SubUp.png"
        	document.getElementById('SubButton'+ID).setAttribute("View", "2")
        	}
        }
        function HideThisSubLinks(ID)
        {
        	if (document.getElementById('SubList'+ID).style.display != "none")
        	{
        	document.getElementById('SubList'+ID).style.display = "none"
        	document.getElementById('SubButton'+ID).getElementsByTagName('IMG')[0].src = "Pictures/SubDown.png"
        	document.getElementById('SubButton'+ID).setAttribute("View", "1")
        	}
        }
        

        Es ist unperformant, immer wieder dasselbe Element aus dem DOM rauszusuchen. Das solltest du einmal tun und die Referenz auf das Objekt in einer Variablen speichern:

        function ShowThisSubLinks(ID)
        {
        	var thisSubLinks = document.getElementById('SubList'+ID);
        
        	if (thisSubLinks.style.display == "none")
        	{
        		thisSubLinks.style.display = ""	
        		thisSubLinks.getElementsByTagName('IMG')[0].src = "Pictures/SubUp.png"
        		thisSubLinks.setAttribute("View", "2")
        	}
        }
        
        function HideThisSubLinks(ID)
        {
        	var thisSubLinks = document.getElementById('SubList'+ID);
        
        	if (thisSubLinks.style.display != "none")
        	{
        		thisSubLinks.style.display = "none"
        		thisSubLinks.getElementsByTagName('IMG')[0].src = "Pictures/SubDown.png"
        		thisSubLinks.setAttribute("View", "1")
        	}
        }
        

        Der Alternativtext fürs Icon wäre ebenfalls noch zu tauschen – wenn nicht einer wie „Untermenü anzeigen/verbergen“ verwendet wird.

        Da beide Funktionen ziemlich ähnlich sind, wäre zu überlegen, ob es nicht sinnvoller ist, sie in einer Funktion ToggleThisSubLinks(ID) zusammenzufassen.

        LLAP 🖖

        --
        „Wir haben deinen numidischen Schreiber aufgegriffen, o Syndicus.“
        „Hat auf dem Forum herumgelungert …“
        (Wachen in Asterix 36: Der Papyrus des Cäsar)