Don P: onmouseout verschluckt...

Hallo Leute,

Es ist zum Verzweifeln:
In einem div-Container stehen mehrere Absätze:

<div id="mySection" name="myName">  
  
  <p id="p17"><span><input id="r0" type="button" value="x"><div>Text1</div><input id="i0" type="button" value="+"></span></p>  
  <p id="p16"><span><input id="r1" type="button" value="x"><div>Text2</div><input id="i1" type="button" value="+"></span></p>  
  <p id="p15"><span><input id="r2" type="button" value="x"><div>Text3</div><input id="i2" type="button" value="+"></span></p>  
  <!-- usw. -->  
  
</div>

Die input-Buttons sind zunächt per JS versteckt (style="visibility:hidden;"). Sie sollen nur sichtbar werden, wenn man mit der Maus auf das div-Element im Absatz zeigt, und wieder verschwinden, wenn man den Zeiger hinausbewegt. (Mit dem "x"-Button kann man dann den Absatz löschen, mit dem "+"-Button einen neuen eingefügen).

Zunächst wollte ich das mit "onmouseover" und "onmouseout" erledigen, aber der Eventhlandler sieht jetzt einfach so aus:

document.getElementById("mySection").onmouseout = function (e) {  
  
  e = e||event;  
  var elt = e.target||e.srcElement; // auslösendes DOM-Element ermitteln  
  
  if ( elt.id.match(/^p\d/) ) {     // das p-Element hat ausgelöst:  
  
    e.stopPropagation();            // nicht weiter aufsteigen  
    toggleButtons(elt);             // Funktion zum Ein-/Ausblenden der Buttons ausführen  
  }  
};

Die Funktion zum Ein-/Ausblenden ändert bei jedem Aufruf die Anzeige der Buttons im Absatz: Wenn sie sichtbar sind, weden sie unsichtbar und umgekehrt.

Das funktioniert soweit, weil

  1. jedes Bewegen der Maus auf ein div im Absatz einen mouseout-Event für <p> auslöst, nämlich "raus aus dem umgebenden <p> hinein in ein Element, welches darin eingebettet ist" (=>Buttons einblenden)
  2. jedes Hinausbewegen aus dem Absatz natürlich wiederum einen mouseout-Event für <p> auslöst (=>Buttons ausblenden).

Das Problem ist jetzt aber, dass der Browser (FF) manche Events zu verschlucken scheint: Wenn man zu schnell über die Absätze fährt, dann bleiben in manchen Absätzen die Buttons eingeblendet :-((. Das darf bzw. kann aber doch gar nicht sein, oder?

Gruß, Don P

  1. Hi,

    Es ist zum Verzweifeln:

    Dass Probleme "analysiert" werden, bevor überhaupt fehlerfreier Code vorliegt? Ja.

    Sie sollen nur sichtbar werden, wenn man mit der Maus auf das div-Element im Absatz zeigt

    Es gibt kein DIV-Element im Absatz.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    1. Hallo,

      Die Dinger in der Mitte <p>...<div>TextX</div>...</p> sind keine div-Elemente im Absatz? Die meine ich jedenfalls.

      Gruß, Don P

      1. Hi,

        Die Dinger in der Mitte <p>...<div>TextX</div>...</p> sind keine div-Elemente im Absatz?

        Da du ihm ungültiges HTML lieferst, muss der Browser deinen Fehler korrigieren.
        I.a.R. wird er das so machen, dass er das P-Element vor dem DIV schliesst.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
        1. Hallo,

          Da du ihm ungültiges HTML lieferst, muss der Browser deinen Fehler korrigieren.
          I.a.R. wird er das so machen, dass er das P-Element vor dem DIV schliesst.

          Soso. Das ist mir neu. Dachte, ein DIV ist so eine Art Universalelement, das man überall einsetzen darf. Das habe ich mal irgendwo gelesen...
          Natürlich ist es per CSS aud display:inline; gesetzt. Wird das vom Browser dann nicht wie ein normales inline-Element behandelt?

          Und du meinst also, wenn ich statt dessen ein SPAN nehmen würde, würde der Fehler nicht auftreten? Das wage ich zu bezweifeln.

          Gruß, Don P

          1. Hi,

            Soso. Das ist mir neu. Dachte, ein DIV ist so eine Art Universalelement, das man überall einsetzen darf. Das habe ich mal irgendwo gelesen...

            http://de.selfhtml.org/html/referenz/elemente.htm#div

            Natürlich ist es per CSS aud display:inline; gesetzt. Wird das vom Browser dann nicht wie ein normales inline-Element behandelt?

            Zitat #1594

            Ausserdem ist CSS höchst optional - wie soll es als auf Regelungen, die sich rein aus HTML ergeben, überhaupt irgendeinen Einfluss haben.

            Und du meinst also, wenn ich statt dessen ein SPAN nehmen würde, würde der Fehler nicht auftreten? Das wage ich zu bezweifeln.

            Es geht mir hier erst mal nur um den Punkt, dass eine Fehleranalyse meistens wenig sinnvoll ist, so lange kein fehlerfreier Code vorliegt.

            MfG ChrisB

            --
            Light travels faster than sound - that's why most people appear bright until you hear them speak.
            1. Hallo,

              Und du meinst also, wenn ich statt dessen ein SPAN nehmen würde, würde der Fehler nicht auftreten? Das wage ich zu bezweifeln.

              Es geht mir hier erst mal nur um den Punkt, dass eine Fehleranalyse meistens wenig sinnvoll ist, so lange kein fehlerfreier Code vorliegt.

              Ok, ok, hast ja recht. Irgendwas muss ich übersehen haben, deshalb überhaupt dieser Thread. Das ungültige HTML ist eine Sache, werde ich korrigieren.

              Zuerst hatte ich kein SPAN außen, sondern in der Mitte anstelle der DIVs, wie es sich gehört. Aber es muss etwas außen stehen, weil sonst jedes inline-Element beim Überfahren zu einem mouseout-Event im <p> führt. Und es muss auch ein anderes Tag sein als das in der Mitte, weil das mittlere dynamisch mit getElementsByTagName() vom <p> aus angesteuert und befüllt wird. Ein DIV außen zerschießt mir leider das ganze Absatzlayout und wäre ja HTML-mäßig ebenfalls nicht ok, wie ich inzwischen weiß.

              Es ist m.E. ziemlich blösinnig, dass das Zeigen auf ein inline-Element einen mouseout-Event im *umbegebenden* Element zur Folge hat. Schließlich hat man das ja nicht wirklich verlassen, sondern ist noch drin, und zwar tief. Es ist zum Verzweifeln, wie gesagt...

              Gruß, Don P

              1. Hi,

                Es ist m.E. ziemlich blösinnig, dass das Zeigen auf ein inline-Element einen mouseout-Event im *umbegebenden* Element zur Folge hat. Schließlich hat man das ja nicht wirklich verlassen, sondern ist noch drin, und zwar tief.

                Tja, so ist es aber, immer schon so gewesen.

                Und gängige Workarounds sind auch verfügbar, bspw. zu prüfen, ob das Element, zu dem hin das mouseout stattfindet, Nachfahre des Elements ist, auf dem man auf den Event reagieren will, mittels Element.contains().

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
                1. Hallo,

                  bspw. zu prüfen, ob das Element, zu dem hin das mouseout stattfindet, Nachfahre des Elements ist, auf dem man auf den Event reagieren will, mittels Element.contains().

                  Wie kann ich denn prüfen, zu welchem Element *hin* ein mouseout stattfindet?
                  Kannst du das evtl. etwas näher erläutern, mit einem kl. Beispiel vielleicht?

                  Bin gerade ganz frustriert, weil ich nie gedacht hätte, dass so in kl. Gimmick solche Schwierigkeiten macht...

                  Danke und Gruß, Don P

                  1. Hi,

                    Wie kann ich denn prüfen, zu welchem Element *hin* ein mouseout stattfindet?

                    IE kennt bei diesen Events event.toElement, Alternativen für andere Browser bitte selber suchen, ich weiss sie gerade nicht auswendig.

                    MfG ChrisB

                    --
                    Light travels faster than sound - that's why most people appear bright until you hear them speak.
        2. Hallo,

          Da du ihm ungültiges HTML lieferst, muss der Browser deinen Fehler korrigieren.

          Ok. Jetzt habe ich die DIVs durch <i> ersetzt.

          <p>...<i>TextX</i>...</p>

          Das HTML ist jetzt ok. Der Fehler ist derselbe geblieben.

          Ist das denn eine bekannte Sache, dass Browser nicht *alle* Events auslösen bzw. nicht für jeden Event die passende Handlerfunktion laufen lassen?

          Es funktioniert prima, wenn man nur langsam die Maus bewegt. Fährt man zu schnell, dann greifen eineige "mouseout" anscheinend nicht :-(.

          Gruß, Don P

  2. Hallo,

    Zum Ausprobieren in FireFox hier mal ein valides Beispiel (nach W3C HTML Validator und jslint):

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
    <html><head>  
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">  
    <title>Test</title>  
    <script type="text/javascript">  
      
    	[code lang=javascript]window.onload = function() {  
      
    		var toggleButtons = function(elt){  
      
    			var editButtons = elt.getElementsByTagName('input');  
      
    			for (var i=0; editButtons[i]; i++) {  
      
    				var theButton = editButtons[i], itsVisibility = theButton.style.visibility;  
    				theButton.style.visibility = itsVisibility === 'hidden' ? 'visible' : 'hidden';  
    			}  
    		};  
      
    		document.getElementById("mySection").onmouseout = function (e) {  
      
    		  var elt = e.target;               // auslösendes HTML-Element ermitteln  
      
    		  if ( elt.id.match(/^p\d/) ) {     // ein p-Element hat ausgelöst:  
      
    			  toggleButtons(elt);             // Funktion zum Ein-/Ausblenden seiner Buttons ausführen  
    		  }  
    		};  
    	};
    

    </script>
    </head><body>

    <div id="mySection" style="display:block; width:10em; height:10em; background-color:yellow; border:2px solid red;">  
    
      <p id="p17"><span><input id="r0" type="button" value="x" style="visibility:hidden;"><i>Text1</i><input id="i0" type="button" value="+" style="visibility:hidden;"></span></p>  
      <p id="p16"><span><input id="r1" type="button" value="x" style="visibility:hidden;"><i>Text2</i><input id="i1" type="button" value="+" style="visibility:hidden;"></span></p>  
      <p id="p15"><span><input id="r2" type="button" value="x" style="visibility:hidden;"><i>Text3</i><input id="i2" type="button" value="+" style="visibility:hidden;"></span></p>  
    
    </div>  
    

    </body>
    </html>[/code]

    Fährt man mit der Maus *langsam* über den Text, erscheinen und verschwinden Buttons rechts/links vom Text. So soll es auch sein.
    Fährt man aber schneller, dann bleiben unkontrolliert Buttons sichtbar. Ich stehe vor einem Rätsel.

    Wie würdet ihr denn diese Aufgabe lösen, das es *so* ganz offenbar nicht funktioniert?

    Danke und Gruß, Don P

    1. Hi,

      Fährt man mit der Maus *langsam* über den Text, erscheinen und verschwinden Buttons rechts/links vom Text. So soll es auch sein.
      Fährt man aber schneller, dann bleiben unkontrolliert Buttons sichtbar. Ich stehe vor einem Rätsel.

      Wie würdet ihr denn diese Aufgabe lösen, das es *so* ganz offenbar nicht funktioniert?

      Ich würde erst mal schauen, ob der Fehler wirklich in der Reihenfolge, in der der FF die Events feuert (bzw. dies ggf. unterlässt) liegt - oder vielleicht doch im verarbeitenden Script, welches evtl. von einer anderen Reihenfolge ausgeht und deshalb nicht das gewünschte macht.
      Kontrollausgabe diverser Event-Eigenschaften (Name, target, Ziel) in einem PRE-Element per innerHTML+= wäre dazu günstig, und dann einfach mal ein bisschen mit der Maus hantieren, so dass das beobachtete Verhalten auftritt.

      Das zur Analyse des Problems.
      Zur Umsetzung - ich würde vermutlich hier eher auf Event Delegation verzichten, wenn diese das Ganze verkompliziert, und es mit Events auf den einzelnen Elementen lösen.

      MfG ChrisB

      --
      Light travels faster than sound - that's why most people appear bright until you hear them speak.
      1. Hallo,

        Kontrollausgabe diverser Event-Eigenschaften (Name, target, Ziel) in einem PRE-Element per innerHTML+= wäre dazu günstig, und dann einfach mal ein bisschen mit der Maus hantieren, so dass das beobachtete Verhalten auftritt.

        Gute Idee.

        Zur Umsetzung - ich würde vermutlich hier eher auf Event Delegation verzichten, wenn diese das Ganze verkompliziert, und es mit Events auf den einzelnen Elementen lösen.

        Hatte ich gestern schon probiert, ohne Erfolg.

        Jetzt habe ich aber eine Lösung, die gut funktioniert mit Event Delegation, mouseover statt mouseout, und ohne zusätzliches SPAN in P. Es werden damit wohl einige Events mehr ausgelöst, als nach meinem Verständnis nötig wären, aber wenigstens ist das gewünschte Verhalten erreicht.

        War insgesamt eine schwere Geburt ;-)

        Danke für deine Hilfe,
        Don P

    2. Hallo,

      also wenn du von mir was hören wollen würdest, müsstest du das beispiel auf einen mini-code reduzieren.

      Gruß

      jobo

      1. Hallo,

        Du willst mich veräppeln, oder?
        Das ist bereits Mini-Code. Oder hättest du es lieber komprimiert und verschlüsselt, mit nichtssagenden Variablennamen, ohne whitespace und so?

        Gruß, Don P

        1. Hallo,

          Du willst mich veräppeln, oder?
          Das ist bereits Mini-Code. Oder hättest du es lieber komprimiert und verschlüsselt, mit nichtssagenden Variablennamen, ohne whitespace und so?

          Mh, die Reduktion auf ein Div, wenig Doctype-Krempel etc. bringt einen selbst manchmal der Lösung näher. Aber lass mal gut sein. Die anderen haben dir ja auch nicht geantwortet. Es war deshalb auch von meiner Seite eher ein Raten, woran es liegen könnte. Bei mir lags daran und dabei bleibts auch. Mit veräppeln oder so und auch irgendwelchen aufbrausenden Emotionen hab ich nix am Hut.

          Gruß

          jobo