In jQuery, come posso distinguere tra un clic programmatico e un clic utente?


91

Supponiamo di aver definito un gestore di clic:

$("#foo").click(function(e){

});

Come posso, all'interno del gestore della funzione, sapere se l'evento è stato attivato a livello di programmazione o dall'utente?


Come funziona il programma per attivare un evento a livello di programmazione?
Clayton

5
Perché devi distinguere i casi?
Damien_The_Unbeliever

@Clayton: $x.click()o $x.trigger('click').
mu è troppo breve

Ho riscontrato una situazione con un dispositivo di scorrimento delle immagini che scorreva automaticamente le immagini e lo ha fatto attivando clic sull'elemento di navigazione corretto associato all'immagine. Il problema è che quando l'utente fa clic sul navigatore, la rotazione automatica dovrebbe interrompersi.
Kasapo

2
Funziona con gli ultimi Firefox, Chrome e IE9. Perché non accettare la risposta qui sotto con i voti più alti ?? @kevino
OZZIE

Risposte:


119

Potresti dare un'occhiata all'oggetto evento e. Se l'evento è stata innescata da un vero e proprio scatto, avrai le cose come clientX, clientY, pageX, pageY, ecc dentro ee saranno i numeri; questi numeri sono relativi alla posizione del mouse quando viene attivato il clic ma probabilmente saranno presenti anche se il clic è stato avviato tramite la tastiera. Se l'evento è stato attivato da $x.click()allora non avrai i soliti valori di posizione in e. Potresti anche guardare la originalEventproprietà , che non dovrebbe essere lì se l'evento provenisse $x.click().

Forse qualcosa del genere:

$("#foo").click(function(e){
    if(e.hasOwnProperty('originalEvent'))
        // Probably a real click.
    else
        // Probably a fake click.
});

Ed ecco un piccolo sandbox con cui giocare: http://jsfiddle.net/UtzND/


4
È fantastico ... ho pensato tra me e me "forse gli eventi attivati ​​da jQuery non hanno informazioni sulla posizione del mouse"! w00t!
Kasapo

2
Questo può essere annullato nei browser che supportano createEvent. jsfiddle.net/UtzND/26
Joe Enzminger

2
@JoeEnzminger sì, ma perché dovresti sconfiggere il tuo stesso copione per così dire ...?
OZZIE

3
Sono preoccupato per uno script di terze parti che genera un evento di clic e il mio script lo gestisce presumendo che sia stato generato dall'utente (un clic effettivo).
Joe Enzminger

2
@JoeEnzminger: tutte le scommesse sono disattivate una volta che il tuo codice è nel browser, non c'è niente che puoi fare che non possa essere sconfitto da una persona sufficientemente intelligente. Penso che il meglio che puoi fare sia controllare un sacco di cose: c'è un originalEvent? È il tipo giusto di cosa? Ci sono coordinate da qualche parte? Le coordinate sono coerenti? Le coordinate sono dentro #foo? ...
mu è troppo breve l'

44

È possibile utilizzare un parametro aggiuntivo come indicato nel manuale del trigger jQuery :

$("#foo").click(function(e, from){
    if (from == null)
        from = 'User';
    // rest of your code
});

$('#foo').trigger('click', ['Trigger']);

3
L'unico problema che vedo con questo è che non puoi distinguere tra un normale clic e $x.click()il .click()chiamante deve dirti esplicitamente che lo sta fingendo. Questo può o non può essere un problema a seconda di cosa sta facendo Kevin Owocki.
mu è troppo breve

1
@mu: Non capisco bene la tua differenza tra un clic "normale" (utente?) e quello $x.click()che è eventHandler (per il clic dell'utente, che potrebbe essere "normale")
Shikiryu

1
La differenza è che uno proviene dall'utente ma l'altro dal software. Il falso clic potrebbe provenire da un plug-in o da un altro codice che non può essere modificato per aggiungere argomenti extra. Non sto criticando la tua soluzione, sto solo prendendo nota di alcuni possibili buchi.
mu è troppo breve

Sebbene mu sia corretto e questo non funzionerà in ogni situazione, era esattamente quello che stavo cercando, grazie! Non sapevo di poter passare il parametro extra come una variabile, ma è esattamente ciò di cui avevo bisogno per testare i clic "reali" in una complicata interfaccia utente che tratta alcuni clic "reali" come programmatici. Grazie per entrambe le soluzioni incredibilmente utili!
Phil

9

C'è già una risposta a un'altra domanda.

Come rilevare se un clic () è un clic del mouse o attivato da un codice?

Usa la whichproprietà dell'oggetto evento. Dovrebbe essere undefinedper eventi attivati ​​da codice

$("#someElem").click(function(e) {
    if (e.which) {
        // Actually clicked
    } else {
        // Triggered by code
    }
});

Esempio di JsFiddle: http://jsfiddle.net/interdream/frw8j/

Spero che sia d'aiuto!


2
Non funziona sempre. Ad esempio select, darebbe un e.which==undefinedanche per un evento genuino.
JNF

5

Ho provato tutte le soluzioni di cui sopra, nel mio caso non è stato funzionato nulla. La soluzione sotto ha funzionato per me. Spero che possa aiutare anche te.

$(document).ready(function(){
  //calling click event programmatically
    $("#chk1").trigger("click");
});

$(document).on('click','input[type=checkbox]',function(e) {
		if(e.originalEvent.isTrusted==true){
			alert("human click");
		}
		else{
			alert("programmatically click");
		}
    
    });
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js">
</script>

<input type="checkbox" id="chk1" name="chk1" >Chk1</input>
<input type="checkbox" id="chk2" name="chk2" >Chk2</input>
<input type="checkbox" id="chk3" name="chk3" >Chk3</input>


4

DOM Livello 3 specifica event.isTrusted. Questo è attualmente supportato solo in IE9 + e Firefox (in base ai miei test. Ho anche letto (anche se non studiato a fondo) che può essere sovrascritto in alcuni browser e probabilmente non è ancora pronto al 100% per essere effettivamente attendibile (sfortunatamente).

Questa è una versione modificata del violino di @ mu che funziona su IE e Firefox.


Buon punto. Tuttavia, non credo che nulla sarà solido al 100%. Dovresti mescolare alcuni test per vedere se isTrustedè supportato e non scrivibile. Penso che la vera risposta dipenda dal perché dietro questa domanda e non abbiamo mai scoperto perché.
mu è troppo breve

@mu, sono arrivato a questa domanda dopo averne fatta una simile, ma più generale. Il mio "perché" caso è che voglio assicurarmi di eseguire un'azione (una transazione finanziaria, anche se piccola) se e solo l'utente ha intrapreso un'azione affermativa diretta sulla pagina.
Joe Enzminger

1

Soluzione Vanila js:

document.querySelector('button').addEventListener('click', function (e){
    if(e.isTrusted){
        // real click.
    }else{
        // programmatic click
    }
});

-1

Non parteciperò alla discussione intellettuale, il codice che ha funzionato per me per filtrare .click()ed .trigger('click')è-

$(document).on('click touchstart', '#my_target', function(e) {
    if (e.pageX && e.pageY) { // To check if it is not triggered by .click() or .trigger('click')
        //Then code goes here
    }
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.