2012-05-04 8 views
6

Aquí es una jsFiddle usando POJS que muestran que return false; no impide la propagación del evento: http://jsfiddle.net/Ralt/Lz2Pw/¿Por qué devolver la falsificación detener la propagación con jQuery mientras que no con POJS?

Aquí está otra usando jQuery mostrando que return false;hace detener la propagación del evento: http://jsfiddle.net/Ralt/D5Mtg/

Editar: El uno que me explica por qué jQuery hace esto - difiriendo intencionalmente del comportamiento original - (y dónde en el código) obtiene la respuesta.

Aquí está el código (largo, pero muy fácil de leer):

  • HTML para ambas versiones:

    <div id="parent1"> 
        <div id="child1"><a href="#" id="a1">child1</a></div> 
    </div> 
    
    <div id="parent2"> 
        <div id="child2"><a href="#" id="a2">child2</a></div> 
    </div> 
    
    <div id="parent3"> 
        <div id="child3"><a href="#" id="a3">child3</a></div> 
    </div> 
    
  • POJS:

    document.getElementById('child1').onclick = function(e) { 
        console.log('child1'); 
        e.preventDefault(); 
    }; 
    
    document.getElementById('parent1').onclick = function(e) { 
        console.log('parent1'); 
    }; 
    
    document.getElementById('child2').onclick = function(e) { 
        console.log('child2'); 
        return false; 
    }; 
    
    document.getElementById('parent2').onclick = function(e) { 
        console.log('parent2'); 
    }; 
    
    document.getElementById('child3').onclick = function(e) { 
        console.log('child3'); 
        e.stopPropagation(); 
    }; 
    
    document.getElementById('parent3').onclick = function(e) { 
        console.log('parent3'); 
    }; 
    
  • versión de jQuery :

    $('#child1').click(function(e) { 
        console.log('child1'); 
        e.preventDefault(); 
    }); 
    
    $('#parent1').click(function(e) { 
        console.log('parent1'); 
    }); 
    
    $('#child2').click(function(e) { 
        console.log('child2'); 
        return false; 
    }); 
    
    $('#parent2').click(function(e) { 
        console.log('parent2'); 
    }); 
    
    $('#child3').click(function(e) { 
        console.log('child3'); 
        e.stopPropagation(); 
    }); 
    
    $('#parent3').click(function(e) { 
        console.log('parent3'); 
    }); 
    
+0

Me pregunto si el retorno falso está siendo recogido por el manejo de eventos de jQuery y detiene la propagación allí ... –

+0

Si es así, me gustaría ver dónde :-) Además, ¿por qué estaría haciendo esto? –

+0

Ah, esto podría ser. Vaya a la fuente jQuery (http://code.jquery.com/jquery-1.7.2.js), busque 'event.stopPropagation', esto ocurre justo después de una condición que comprueba si el valor devuelto es falso. –

Respuesta

8

En la línea 3331 de version 1.7.1, en jQuery.event.dispatch:

ret = ((jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler) 
     .apply(matched.elem, args); 

if (ret !== undefined) { 
    event.result = ret; 
    if (ret === false) { 
     event.preventDefault(); 
     event.stopPropagation(); 
    } 
} 

Una gran cantidad de envases ha sucedido antes de esta línea, pero básicamente, se ejecuta la función de controlador (ya sea una función en bruto, o el handler función memeber de handlerObject) usando apply. Si el resultado de esa llamada es falso, lo hace preventDefault y stopPropagation.

Esto se menciona en la documentación de on():

Volviendo false desde un controlador de eventos llamará automáticamente a event.stopPropagation() y event.preventDefault().

En cuanto a ¿por qué lo hicieron? No sé, ya que no soy el equipo de diseño de jQuery, pero supongo que es solo porque return false es mucho más rápido de escribir que event.preventDefault(); event.stopPropagation();. (Y si jQuery no se trata de asegurarse de que tiene que escribir menos, no estoy seguro de qué se trata.)

que no creen el valor de retorno de un controlador de eventos está siempre realmente utilizado en cualquier lugar en POJS (¡alguien correcto si eso está mal!). Por lo tanto, jQuery puede tener una declaración return con seguridad causando efectos secundarios en un controlador (ya que devolver falsa en un manejador POJS no tiene sentido, no se daña la funcionalidad POJS).

+0

¿Por qué hace eso? Esa es mi pregunta principal (pero +1 para mostrar exactamente en qué parte del código). –

+1

Heh, supongo que olvidé el lema. ¡Gracias! –

+3

Porque, por lo general, las personas quieren decir "descartar este evento y no hacer ningún procesamiento adicional sobre él" cuando 'devuelven falso;' en el controlador. – ThiefMaster

Cuestiones relacionadas