Compruebe si el evento es desencadenado por un humano

140

Tengo un controlador adjunto a un evento y me gustaría que se ejecute solo si es activado por un humano, y no por un método trigger (). ¿Cómo noto la diferencia?

Por ejemplo,

$('.checkbox').change(function(e){
  if (e.isHuman())
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change'); //doesn't alert
Dziamid
fuente

Respuestas:

212

Puede verificar e.originalEvent: si está definido, el clic es humano:

Mira el violín http://jsfiddle.net/Uf8Wv/

$('.checkbox').change(function(e){
  if (e.originalEvent !== undefined)
  {
    alert ('human');
  }
});

mi ejemplo en el violín:

<input type='checkbox' id='try' >try
<button id='click'>Click</button>

$("#try").click(function(event) {
    if (event.originalEvent === undefined) {
        alert('not human')
    } else {
        alert(' human');
    }


});

$('#click').click(function(event) {
    $("#try").click();
});
Nicola Peluchetti
fuente
1
@Nicola ¿Está documentado en alguna parte?
Šime Vidas
@Sime, no lo sé, pero creo que es estándar. mira aquí: api.jquery.com/category/events/event-object
Nicola Peluchetti
@Nicola Ya veo, es una cosa jQuery. jQuery almacena el objeto de evento original dentro de esta propiedad. Por cierto, ¿qué quieres decir con que no sabes? Acaba de proporcionar el enlace a la documentación:)
Šime Vidas
1
Parece que también puedes usarevent.isTrigger
avoliva
1
@Anurag, me encontraba con el mismo problema en este momento. Parece que jQuery se llena originalEventcuando el evento se desencadena DOM.click(), pero puede usarlo $($("#try")[0]).click();, que es torpe, pero funciona.
Daniel Garrett
19

Más sencillo que el anterior sería:

$('.checkbox').change(function(e){
  if (e.isTrigger)
  {
    alert ('not a human');
  }
});

$('.checkbox').trigger('change'); //doesn't alert
Kenneth Spencer
fuente
Esta es la mejor respuesta. Para obtener más información, consulte: stackoverflow.com/questions/10704168/…
jaredjacobs
3
Si bien esto es tentador y probablemente acogedor en la práctica, tenga en cuenta que los desarrolladores de jQuery no desean graduarse isTriggeren la API pública a partir de este momento .
Jon
7

Creo que la única forma de hacerlo sería pasar un parámetro adicional en la triggerllamada según la documentación .

$('.checkbox').change(function(e, isTriggered){
  if (!isTriggered)
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change', [true]); //doesn't alert

Ejemplo: http://jsfiddle.net/wG2KY/

detaylor
fuente
1
puede consultar la propiedad original Evento del objeto del evento: si el evento no proviene de un clic, no está definido
Nicola Peluchetti
1
Por alguna razón, event.originalEvent no funcionaba para mí (solo seguía retrocediendo 1) cuando usaba el controlador 'clic' de Zepto. Así que probé la solución anterior. Trabajado como un encanto.
Larrydx
7

La respuesta aceptada no funcionó para mí. Han pasado 6 años y jQuery ha cambiado mucho desde entonces.

Por ejemplo, event.originalEventsiempre regresa truecon jQuery 1.9.x. Quiero decir que el objeto siempre existe pero el contenido es diferente.

Aquellos que usan versiones más nuevas de jQuery pueden probar esta. Funciona en Chrome, Edge, IE, Opera, FF

if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
    //Hey hooman it is you
}
Ergec
fuente
3

Actualmente la mayoría de los navegadores soportan event.isTrusted :

if (e.isTrusted) {
  /* The event is trusted: event was generated by a user action */
} else {
  /* The event is not trusted */
}

De documentos :

El IsTrusted propiedad de la de sólo lectura Eventinterfaz es una Boolean que es verdadera cuando el evento fue generada por una acción del usuario, y la falsa cuando el evento fue creado o modificado por una secuencia de comandos o enviado a través de EventTarget.dispatchEvent () .

felipsmartins
fuente
0

Puede usar onmousedown para detectar el clic del mouse frente a la llamada trigger ().

Boateng
fuente
Es posible que no trabaje en el siguiente escenario: a veces es posible seleccionar los elementos de la página con la tecla Tab. Por ejemplo, si he seleccionado de esta manera una casilla de verificación, puedo marcar / desmarcar usando la tecla de espacio. O incluso abrir un drodpdown usando la tecla de flecha hacia abajo.
Diego Favero el
0

Pensaría en una posibilidad en la que verifique la posición del mouse, como:

  • Hacer clic
  • Obtener la posición del mouse
  • Superpone los acordes del botón.
  • ...
Luke
fuente
Es posible que no trabaje en el siguiente escenario: a veces es posible seleccionar los elementos de la página con la tecla Tab. Por ejemplo, si he seleccionado de esta manera una casilla de verificación, puedo marcar / desmarcar usando la tecla de espacio. O incluso abrir un drodpdown usando la tecla de flecha hacia abajo.
Diego Favero el
0

En caso de que tenga control de todo su código, no hay llamadas extraterrestres $(input).focus()que setFocus().

Usar una variable global es una forma correcta para mí.

var globalIsHuman = true;

$('input').on('focus', function (){
    if(globalIsHuman){
        console.log('hello human, come and give me a hug');
    }else{
        console.log('alien, get away, i hate you..');
    }
    globalIsHuman = true;
});

// alien set focus
function setFocus(){
    globalIsHuman = false;
    $('input').focus();
}
// human use mouse, finger, foot... whatever to touch the input

Si algún extraterrestre todavía quiere llamar $(input).focus()desde otro planeta. Buena suerte o mira otras respuestas

vanduc1102
fuente
Esto solo evita que las personas llamen setFocus(), no evita que las personas activen el evento de enfoque. No escribir setFocus()en absoluto también evitaría que las personas lo llamen, así que no veo el beneficio. De hecho, la gente aún podría llamar $('input').focus()y hacer que pasara.
Rob
wow, primera vez que alguien comentario justo después de que respondieron a la pregunta, voy a actualizar la respuesta
vanduc1102
Si está trabajando en un entorno cerrado sin otra secuencia de comandos de terceros, esto funcionaría en un mundo perfecto. Sin embargo, las aplicaciones más prácticas son para sitios de clientes que tienen todo tipo de complementos y scripts agregados que muy bien pueden llamar a ese enfoque. Una cosa que podría ayudar a esto es envolver su código (y cualquier código que necesite llamar a esa función) en una función de alcance como esta: (function(){/*your code here*/})();Esto mantendría la función setFocus a salvo de ser invocada y el booleano de ser modificado por scripts externos.
Xandor