2012-08-07 13 views
14

Estoy tratando de entender qué determina el orden en que se desencadenan los controladores de eventos al hacer clic en un <div> anidado; lo que veo parece estar en desacuerdo con el comportamiento documentado, así que estoy buscando un poco de ayuda para entenderlo.Detectores de eventos registrados para capturar fase no activada antes del burbujeo, ¿por qué?

tengo 2 divs anidados, y tengo 2 controladores de eventos unidos a cada, uno para la fase de captura, y uno para la fase de propagación:

<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> 

Según what I have read la salida debe ser:

outer true 
inner true 
inner false 
outer false 

pero lo que realmente veo (en Chrome y Firefox) es:

outer true 
inner false 
inner true 
outer false 

¿Alguien puede explicar la discrepancia?

Respuesta

15

La especificación de flujo de eventos de W3C (es decir, lo que implementan Chrome y Firefox) es que todos los eventos se capturan primero hasta que alcanzan el elemento de destino, momento en el que vuelven a burbujear. Sin embargo, cuando el flujo del evento alcanza el objetivo del evento en sí mismo, el evento ya no captura ni burbujea: está en el objetivo mismo. Como el burbujeo/captura no es aplicable, los controladores de eventos disparan en el orden en el que están registrados. Intente intercambiar el orden de los controladores de eventos de su elemento interno, encontrará que también cambia el orden de salida de la consola.

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

Más recientes revisiones de la DOM Evento spec hacen de este punto más claro (http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html):

burbujeante fase El proceso por el que un evento puede ser manejado por uno de los antecesores del objetivo después de está siendo manejado por el objetivo del evento. Consulte la descripción de la fase de burbuja en el contexto del flujo de eventos para obtener más detalles.

fase de captura El proceso por el que un evento puede ser manejado por uno de antepasados ​​del objetivo antes siendo manejado por el destino del evento. Consulte la descripción de la fase de captura en el contexto de flujo de eventos para más detalles.

+1

Así que mi opinión es que la captura debe ocurrir antes de la formación de burbujas en todos los elementos (incluyendo interno) pero eso no es lo que estoy viendo - en el interior del burbujeante (falso) ocurre antes de capturar (verdadero) Cuando – codebox

+5

agregue un controlador de eventos al objetivo del evento en sí, burbuja contra captura no es aplicable. En ese nivel, no estás capturando ni burbujeando: estás en el objetivo mismo. Los controladores de eventos disparan en el orden en el que se registraron. Las versiones más recientes de la especificación son más claras en este punto: dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html (Ctrl + F -> fase de burbujeo) –

+0

@ElliotB . Entonces, ¿cómo lo registramos en la fase de captura? es esto posible? – Pacerier

Cuestiones relacionadas