Aquí es una demo (jsfiddle) con unas formas y dos campos:
<div id="container">
<form>
<div class="field">
<input id="demo" type="text" name="demo" />
</div>
<div class="field">
<input id="demo2" type="text" name="demo2" />
</div>
</form>
</div>
El código es el siguiente:
$(document).ready(function() {
$('#container').click(function(evt) {
if(this == evt.target) {
console.log('clicked container',evt.target);
$('#demo').focus();
} else {
console.log('clicked child -> ignoring');
}
});
$('.field').click(function(evt) {
if(this == evt.target) {
console.log('clicked field div',evt.target);
$(this).find('input').focus();
} else {
console.log('clicked child -> ignoring');
}
});
});
Puede clic en el contenedor que contiene el formulario para establecer el foco en el primer campo de entrada o detrás del campo de entrada para establecer el foco en él.
Si hace clic en el campo, se ignorará el clic.
El código anterior funciona desde jQuery asigna el nodo DOM para this
antes de llamar a los controladores de eventos, por lo que se puede comprobar fácilmente si el evento actual fue publicado por el nodo DOM comprobando
this == evt.target
CSS:
#container {
width: 600px;
height: 600px;
background: blue;
}
.field {
background: green;
}
Se siente un poco "exagerado" para agregar un controlador de clic a cada enlace solo para evitar la propagación de eventos (por supuesto, depende de la cantidad de enlaces). Pero esta es una buena forma de evitar la propagación de eventos para cualquier elemento específico. –
@Felix - Si hay muchos enlaces, tomaría un enfoque completamente distinto con un conjunto de manejadores '.delegate()' :) (podría usar una versión delegada de lo anterior * antes * del otro manejador de clics también) . –
Acabo de probar con 'delegate()' y no funciona para mí: http://jsfiddle.net/cxcfA/. Supongo que porque el evento ya se hizo borroso. ¿O quieres decir algo más? –