Wie kann ich in jQuery zwischen einem programmatischen und einem Benutzerklick unterscheiden?

91

Angenommen, ich habe einen Klick-Handler definiert:

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

});

Wie kann ich im Funktionshandler feststellen, ob das Ereignis programmgesteuert oder vom Benutzer ausgelöst wurde?

Kevin Owocki
quelle
Wie löst das Programm ein Ereignis programmgesteuert aus?
Clayton
5
Warum müssen Sie die Fälle unterscheiden?
Damien_The_Unbeliever
@ Clayton: $x.click()oder $x.trigger('click').
Mu ist zu kurz
Ich hatte eine Situation mit einem Bildschieberegler, der automatisch durch die Bilder gescrollt hat, und zwar durch Auslösen von Klicks auf das richtige Navigationselement, das dem Bild zugeordnet ist. Das Problem ist, wenn der Benutzer auf das Navigationsgerät klickt, sollte die automatische Drehung gestoppt werden.
Kasapo
2
Dies funktioniert in den neuesten Firefox, Chrome und IE9. Warum nicht die Antwort unten mit den höchsten Stimmen annehmen? @ kevino
OZZIE

Antworten:

119

Sie können sich das Ereignisobjekt ansehen e. Wenn das Ereignis von einem echten Klick ausgelöst wurde, haben Sie Dinge wie clientX, clientY, pageX, pageY, etc. im Inneren eund sie werden Zahlen sein; Diese Zahlen beziehen sich auf die Mausposition, wenn der Klick ausgelöst wird, sind jedoch wahrscheinlich auch dann vorhanden, wenn der Klick über die Tastatur ausgelöst wurde. Wenn das Ereignis von ausgelöst wurde, haben $x.click()Sie nicht die üblichen Positionswerte in e. Sie könnten auch an der aussehen originalEventEigenschaft , die nicht da sein sollte , wenn das Ereignis herkommt $x.click().

Vielleicht so etwas:

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

Und hier ist eine kleine Sandbox zum Spielen: http://jsfiddle.net/UtzND/

mu ist zu kurz
quelle
4
Das ist großartig ... Ich dachte nur bei mir: "Vielleicht haben von jQuery ausgelöste Ereignisse keine Mauspositionsinformationen." w00t!
Kasapo
2
Dies kann in Browsern, die createEvent unterstützen, behoben werden. jsfiddle.net/UtzND/26
Joe Enzminger
2
@JoeEnzminger ja aber warum würdest du sozusagen dein eigenes script besiegen ...?
OZZIE
3
Ich mache mir Sorgen, dass ein Skript eines Drittanbieters ein Klickereignis generiert und mein Skript es unter der Annahme verarbeitet, dass es vom Benutzer generiert wurde (ein tatsächlicher Klick).
Joe Enzminger
2
@JoeEnzminger: Alle Wetten sind geschlossen, sobald sich Ihr Code im Browser befindet. Sie können nichts tun, was von einer ausreichend klugen Person nicht besiegt werden kann. Ich denke, das Beste, was Sie tun können, ist eine Reihe von Dingen zu überprüfen: Gibt es eine originalEvent? Ist es das Richtige? Gibt es irgendwo Koordinaten? Sind die Koordinaten konsistent? Sind die Koordinaten drin #foo? ...
mu ist zu kurz
44

Sie können einen zusätzlichen Parameter verwenden, wie im Handbuch zum jQuery-Trigger angegeben :

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

$('#foo').trigger('click', ['Trigger']);
Shikiryu
quelle
3
Das einzige Problem, das ich dabei sehe, ist, dass Sie nicht zwischen einem normalen Klick unterscheiden können und $x.click()der .click()Anrufer Ihnen explizit mitteilen muss, dass er es vortäuscht. Dies kann ein Problem sein oder auch nicht, je nachdem, was Kevin Owocki vorhat.
Mu ist zu kurz
1
@ Mu: Ich verstehe Ihren Unterschied zwischen einem "normalen" Klick (Benutzer?) und dem $x.click()EventHandler (für Benutzer-Klick, der "normal" sein kann) nicht ganz
Shikiryu
1
Der Unterschied besteht darin, dass einer vom Benutzer stammt, der andere von der Software. Der gefälschte Klick kann von einem Plugin oder einem anderen Code stammen, der nicht geändert werden kann, um die zusätzlichen Argumente hinzuzufügen. Ich kritisiere Ihre Lösung nicht, sondern stelle nur einige mögliche Lücken fest.
Mu ist zu kurz
Obwohl mu richtig ist und dies nicht in jeder Situation funktionieren wird, war es genau das, wonach ich gesucht habe, danke! Ich wusste nicht, dass ich den zusätzlichen Parameter wie eine Variable übergeben kann, aber genau das musste ich auf "echte" Klicks in einer komplizierten Benutzeroberfläche testen, die einige "echte" Klicks als programmatisch behandelt. Vielen Dank für beide unglaublich nützlichen Lösungen!
Phil
9

Es ist bereits eine andere Frage beantwortet.

Wie erkenne ich, ob ein Klick () ein Mausklick ist oder durch einen Code ausgelöst wird?

Verwenden Sie die whichEigenschaft des Ereignisobjekts. Es sollte undefinedfür Code-ausgelöste Ereignisse sein

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

JsFiddle-Beispiel - http://jsfiddle.net/interdream/frw8j/

Ich hoffe es hilft!

Swanidhi
quelle
2
Funktioniert nicht immer. ZB selectwürde ein e.which==undefinedAusgleich für ein echtes Ereignis geben.
JNF
5

Ich habe alle oben genannten Lösungen ausprobiert. In meinem Fall wurde nichts funktioniert. Die folgende Lösung hat bei mir funktioniert. Hoffe es wird dir auch helfen.

$(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>

GSB
quelle
4

DOM Level 3 gibt event.isTrusted an. Dies wird derzeit nur in IE9 + und Firefox unterstützt (basierend auf meinen Tests. Ich habe auch gelesen (obwohl nicht gründlich recherchiert), dass es in einigen Browsern überschrieben werden kann und wahrscheinlich noch nicht zu 100% bereit ist, tatsächlich vertrauenswürdig zu sein (leider).

Dies ist eine modifizierte Version von @ mus Geige, die unter IE und Firefox funktioniert.

Joe Enzminger
quelle
Guter Punkt. Ich denke jedoch nicht, dass irgendetwas 100% solide sein wird. Sie müssten einige Tests isTrustedeinmischen, um festzustellen, ob sie unterstützt und nicht beschreibbar sind. Ich denke, die wirkliche Antwort hängt vom Warum hinter dieser Frage ab, und wir haben nie herausgefunden, warum.
Mu ist zu kurz
@mu, ich bin zu dieser Frage gekommen, nachdem ich eine ähnliche, aber allgemeinere Frage gestellt habe. Mein "Warum" -Fall ist, dass ich sicherstellen möchte, dass ich nur dann eine Aktion ausführe (eine finanzielle Transaktion, wenn auch eine kleine), wenn der Benutzer eine direkte positive Aktion auf der Seite ausgeführt hat.
Joe Enzminger
1

Vanila js Lösung:

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

Nicht gehen in der intellektuellen Diskussion teilzunehmen, den Code, der für mich Filter gearbeitet .click()und .trigger('click')is-

$(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
    }
});
Sahu V Kumar
quelle