2012-08-07 13 views
14

Ich versuche zu verstehen, was die Reihenfolge bestimmt, in der Event-Handler ausgelöst werden, wenn Sie auf ein verschachteltes klicken <div> - was ich sehe, scheint im Widerspruch zu dokumentiertem Verhalten zu sein, also suche ich ein wenig Hilfe, um es zu verstehen.Ereignis-Listener, die für die Erfassungsphase registriert sind, werden nicht vor dem Blasen ausgelöst - warum?

Ich habe 2 verschachtelten divs, und ich habe 2 Event-Handler jeweils an, eine für die Erfassung Phase, und einen für die Bubbling-Phase:

<html> 
    <head> 
     <script> 
      function setup(){ 
       var outer = document.getElementById('outer'); 
       outer.addEventListener('click', function(){console.log('outer false');}, false); 
       outer.addEventListener('click', function(){console.log('outer true');}, true); 

       var inner = document.getElementById('inner'); 
       inner.addEventListener('click', function(){console.log('inner false');}, false); 
       inner.addEventListener('click', function(){console.log('inner true');}, true); 
      }   
     </script> 
     <style> 
      div { 
       border: 1px solid; 
       padding: 1em; 
      } 
     </style> 
    </head> 
    <body onload="setup()"> 
     <div id="outer"> 
      <div id="inner"> 
       CLICK 
      </div> 
     </div> 
    </body> 
</html> 

Nach what I have read sollte die Ausgabe sein:

outer true 
inner true 
inner false 
outer false 

aber was ich sehe tatsächlich (auf Chrome und Firefox) ist:

outer true 
inner false 
inner true 
outer false 

Kann jemand die Diskrepanz erklären?

Antwort

15

W3C-Event-Flow-Spezifikationen (d. H. Was Chrome und Firefox implementieren) ist, dass alle Ereignisse zuerst erfasst werden, bis sie das Zielelement erreichen. An diesem Punkt steigen sie wieder auf. Wenn der Ereignisfluss jedoch das Ereignisziel selbst erreicht, wird das Ereignis nicht mehr erfasst oder übersprudelt - es befindet sich auf dem Ziel selbst. Da das Bubbling/Capturing nicht anwendbar ist, werden die Ereignishandler in der Reihenfolge ausgelöst, in der sie registriert sind. Versuchen Sie, die Reihenfolge der Event-Handler für innere Elemente zu vertauschen. Sie werden feststellen, dass auch die Reihenfolge der Konsolenausgabe geändert wird.

jsFiddle Beispiel: http://jsfiddle.net/RTfwd/1/

Neuere Versionen des DOM-Event-SPEC In diesem Punkt deutlicher machen (http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html):

Phase sprudelt Der Prozess, bei dem ein Ereignis von gehandhabt werden kann einer der Vorfahren des Ziels nach wird von dem Ereignisziel behandelt. Weitere Informationen finden Sie in der Beschreibung der Bubble-Phase im Kontext des Ereignisflusses.

Erfassungsphase Der Prozess, bei dem ein Ereignis kann von einem das Ziel Vorfahr vor gehandhabt durch das Ereignisziel behandelt werden. Siehe die Beschreibung der Erfassungsphase im Kontext des Ereignisflusses für weitere Details.

+1

Also mein Verständnis ist, dass die Erfassung vor dem sprudelnden auf alle Elemente (einschließlich Innen), aber das ist nicht das, was ich sehe auftreten sollte - Sie inneren der sprudelnden (false) geschieht vor der Aufnahme (true) – codebox

+5

Wenn Fügen Sie dem Ereignisziel selbst einen Ereignishandler hinzu. Bubble vs Capture ist nicht anwendbar. Auf dieser Ebene fängt man nicht an zu blubbern - man ist auf dem Ziel selbst. Die Ereignishandler werden in der Reihenfolge ausgelöst, in der sie registriert wurden. Neuere Versionen der Spezifikation sind in diesem Punkt klarer: dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html (Strg + F -> sprudelnde Phase) –

+0

@EliotB ., Wie können wir es in der Erfassungsphase registrieren? ist das überhaupt möglich? – Pacerier

Verwandte Themen