javascript - invocar - llamar evento click desde jquery
¿Cómo debo disparar el evento de desenfoque de JavaScript después de hacer clic en el evento que causa el desenfoque? (6)
Me he encontrado con este problema varias veces y no estoy satisfecho con las soluciones que he usado antes.
Tengo un cuadro de entrada con un evento borroso que valida el contenido del mismo y un botón que completará el cuadro de entrada al hacer clic. El problema es hacer clic en el botón dispara el evento de desenfoque de entrada y luego el evento de clic de botón para que el contenido insertado por el botón no sea lo que se valida.
Ver http://jsfiddle.net/jakecr/dL3K3/
Sé que este es el comportamiento correcto, pero no puedo pensar en una forma clara de solucionar el problema.
A veces es útil obtener un objeto secundario en el mouseup, pero el padre quiere ocultar sus hijos en blur. Podemos cancelar el ocultamiento de los elementos secundarios, luego esperar hasta que aparezca nuestro mouseup, luego forzar la borrosidad para que ocurra cuando estemos listos
js
var cancelHide = false;
$(''.my-input'').blur(function() {
if (!cancelHide) {
$(''.my-item'').hide();
}
});
$(''.my-input'').click(function() {
$(''.my-item'').show();
});
$(''.my-item'').mousedown(function() {
cancelHide = true;
});
$(''.my-item'').mouseup(function() {
var text = $(this).text();
alert(text);
cancelHide = false;
$(''.my-input'').blur();
});
html
<input type="text" class="my-input"/>
<div class="my-item">Hello</div>
<div class="my-item">Lovely</div>
<div class="my-item">World</div>
css
.my-item {
display:none;
}
https://jsfiddle.net/tic84/on421rxg/
Al hacer clic en los elementos de la lista, solo se alertará en el mouseup, a pesar de que el padre intente ocultarlos en el desenfoque.
El truco consiste en no utilizar borrosidad y hacer clic en los eventos, ya que siempre se realizan en orden de desenfoque primero, haga clic en segundo. En su lugar, debe verificar cuándo ha cambiado el elemento que tiene foco, porque eso solo ocurre después del clic.
Creo que tengo una solución elegante para este:
var alreadyValidated = ''true'';
setInterval(function(){
if(document.activeElement.id != ''validation-field-id''){
if(alreadyValidated==''false''){
alreadyValidated = ''true'';
validate(document.activeElement);
}
}
else {
alreadyValidated = ''false'';
}
}, 200);
Actualmente, todos los navegadores modernos son compatibles con document.activeElement.
Esto también podría ayudar:
Establezca un temporizador que retrase la acción del evento de desenfoque antes de que se dispare el evento de clic del botón.
// Namespace for timer var setTimer = { timer: null }
$(''input,select'').blur(function () {
setTimer.timer = setTimeout(function () {
functionCall();
}, 1000);
});
$(''input,select'').focus(function () {
setTimer.timer = setTimeout(function () {
functionCall();
}, 1000);
});
$("#btn").click(function () {
clearTimeout(setTimer.timer);
functionCall();
});
Separe la lógica de validación de entrada de su propia función, que se llama tanto por el evento de desenfoque de forma automática y luego por el evento de clic después de haber modificado el valor en el cuadro de entrada. Es cierto que su lógica de validación se llamaría dos veces, pero no estoy viendo una forma de evitarlo sin hacer muchos más cambios.
Ejemplo usando jQuery:
$(''input'').blur(function() {
validate(this);
});
$(''submit'').click(function() {
//modify the input element
validate(inputElement);
});
var validate = function(obj) {
// validate the object
}
Tengo una solución mejor que la de Yoni Jah: invocar preventDefault en el evento mousedown del botón. El onBlur nunca sucede, así que puedes hacer lo que quieras en el evento click.
Esto es mejor porque no cambia el comportamiento del clic al hacer que las cosas sucedan con el mouse hacia abajo en lugar de hacia arriba, lo que puede ser inesperado.
Tuvimos un problema similar en el trabajo. lo que descubrimos al final fue que el evento de mousedown se disparará antes del evento de desenfoque, lo que le permite establecer el contenido antes de la validación o incluso cancelar el proceso de validación por completo con un indicador.
mira este violín que hice usando tu ejemplo- http://jsfiddle.net/dL3K3/31/
$(function(){
var flag = true;
$(''input'').blur(function(){
if(!$(this).val() && flag){
alert("Grrr, It''s empty");
}
});
$(''button'').mousedown(function(){
flag = false;
});
$(''button'').mouseup(function(){
flag = true;
$(''input'').val(''content'').focus();
});
});
-Editar-
Como @mclin Sugerido, usar el evento mousedown y preventDefault evitará el comportamiento borroso. Y puedes dejar intacto el evento clic original -
http://jsfiddle.net/dL3K3/364/
$(function(){
$(''input'').blur(function(){
if(!$(this).val()){
alert("Grrr, It''s empty");
}
});
$(''button'').mousedown(function(e){
e.preventDefault();
});
$(''button'').click(function(){
$(''input'').val(''content'');
});
});
Esta solución puede ser un poco más limpia y mejor para la mayoría de los casos, solo tenga en cuenta que si la usa evitará Por defecto y borrosidad de cualquier otro elemento en el que se enfoque actualmente, pero para la mayoría de los casos de uso eso no debería ser un problema.