Di jQuery, bagaimana cara membedakan antara klik terprogram dan pengguna?

91

Katakanlah saya memiliki penangan klik yang ditentukan:

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

});

Bagaimana saya, di dalam penangan fungsi, mengetahui apakah peristiwa itu diaktifkan secara terprogram, atau oleh pengguna?

Kevin Owocki
sumber
Bagaimana cara program menjalankan acara secara terprogram?
Clayton
5
Mengapa Anda perlu membedakan kasusnya?
Damien_The_Unbeliever
@Clayton: $x.click()atau $x.trigger('click').
mu terlalu pendek
Saya mengalami masalah dengan penggeser gambar yang secara otomatis menggulir gambar, dan melakukannya dengan memicu klik pada item navigasi yang benar yang terkait dengan gambar. Masalahnya, ketika pengguna mengklik navigasi, rotasi otomatis harus berhenti.
Kasapo
2
Ini berfungsi di firefox terbaru, chrome dan IE9. Mengapa tidak menerima jawaban di bawah ini dengan suara terbanyak ?? @kevino
OZZIE

Jawaban:

119

Anda bisa melihat objek acara e. Jika acara ini dipicu oleh klik nyata, Anda akan memiliki hal-hal suka clientX, clientY, pageX, pageY, dll di dalam edan mereka akan angka; angka-angka ini terkait dengan posisi mouse saat klik dipicu tetapi angka tersebut mungkin akan ada meskipun klik dimulai melalui keyboard. Jika peristiwa dipicu olehnya, $x.click()Anda tidak akan memiliki nilai posisi yang biasa di e. Anda juga dapat melihat originalEventproperti , yang seharusnya tidak ada di sana jika acara tersebut berasal $x.click().

Mungkin sesuatu seperti ini:

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

Dan inilah kotak pasir kecil untuk dimainkan: http://jsfiddle.net/UtzND/

mu terlalu pendek
sumber
4
Itu luar biasa ... Saya hanya berpikir "mungkin peristiwa yang dipicu jQuery tidak memiliki informasi posisi mouse"! w00t!
Kasapo
2
Ini bisa dikalahkan di browser yang mendukung createEvent. jsfiddle.net/UtzND/26
Joe Enzminger
2
@JoeEnzminger ya tapi mengapa Anda mengalahkan skrip Anda sendiri sehingga untuk berbicara ...?
OZZIE
3
Saya khawatir tentang skrip pihak ketiga yang menghasilkan peristiwa klik dan skrip saya menanganinya dengan asumsi bahwa itu dibuat oleh pengguna (klik sebenarnya).
Joe Enzminger
2
@JoeEnzminger: Semua taruhan dibatalkan setelah kode Anda ada di browser, tidak ada yang dapat Anda lakukan yang tidak dapat dikalahkan oleh orang yang cukup pintar. Saya pikir hal terbaik yang dapat Anda lakukan adalah memeriksa banyak hal: Apakah ada originalEvent? Apakah ini hal yang benar? Apakah ada koordinat di mana saja? Apakah koordinatnya konsisten? Apakah koordinatnya ada di dalam #foo? ...
mu terlalu pendek
44

Anda dapat menggunakan parameter tambahan seperti yang dinyatakan dalam manual pemicu jQuery :

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

$('#foo').trigger('click', ['Trigger']);
Shikiryu
sumber
3
Satu-satunya masalah yang saya lihat adalah bahwa Anda tidak dapat membedakan antara klik normal dan $x.click(), .click()penelepon harus secara eksplisit memberi tahu Anda bahwa mereka memalsukannya. Ini mungkin atau mungkin tidak menjadi masalah tergantung pada apa yang sedang dilakukan Kevin Owocki.
mu terlalu pendek
1
@mu: Saya tidak begitu mengerti perbedaan Anda antara klik "normal" (pengguna?) dan $x.click()yang merupakan eventHandler (untuk klik pengguna, yang mungkin "normal")
Shikiryu
1
Perbedaannya adalah yang satu berasal dari pengguna tetapi yang lain dari perangkat lunak. Klik palsu mungkin berasal dari plugin atau beberapa kode lain yang tidak dapat dimodifikasi untuk menambahkan argumen tambahan. Saya tidak mengkritik solusi Anda, hanya mencatat beberapa kemungkinan lubang.
mu terlalu pendek
Meskipun mu benar dan ini tidak akan berfungsi dalam setiap situasi, itu persis seperti yang saya cari, terima kasih! Tidak tahu saya bisa meneruskan parameter ekstra seperti var, tetapi itulah yang saya perlukan untuk menguji klik "nyata" di UI yang rumit yang memperlakukan beberapa klik "nyata" sebagai terprogram. Terima kasih untuk kedua solusi yang sangat berguna!
Phil
9

Ada pertanyaan lain yang sudah terjawab.

Bagaimana cara mendeteksi jika klik () adalah klik mouse atau dipicu oleh beberapa kode?

Gunakan whichproperti objek acara. Ini harus undefineduntuk acara yang dipicu kode

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

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

Semoga membantu!

Swanidhi
sumber
2
Tidak selalu berhasil. Misalnya selectakan memberikan e.which==undefinedbahkan untuk acara asli.
JNF
5

Saya telah mencoba semua solusi di atas. Tidak ada yang berhasil dalam kasus saya. Solusi di bawah ini berhasil untuk saya. Semoga ini akan membantu Anda juga.

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

DOM Level 3 menentukan event.isTrusted. Ini hanya saat ini didukung di IE9 + dan Firefox (berdasarkan pengujian saya. Saya juga membaca (meskipun belum diteliti secara menyeluruh) bahwa ini dapat diganti di beberapa browser dan mungkin belum 100% siap untuk dipercaya (sayangnya).

Ini adalah versi modifikasi dari biola @ mu yang berfungsi di IE dan Firefox.

Joe Enzminger
sumber
Poin yang bagus. Saya tidak berpikir apa pun akan 100% solid. Anda harus menggabungkan beberapa pengujian untuk melihat apakah isTrusteddidukung dan tidak dapat ditulisi. Saya pikir jawaban sebenarnya tergantung pada mengapa di balik pertanyaan ini dan kami tidak pernah tahu mengapa.
mu terlalu pendek
@mu, saya sampai pada pertanyaan ini setelah menanyakan pertanyaan yang serupa, tetapi lebih umum. Kasus "mengapa" saya adalah saya ingin memastikan bahwa saya hanya melakukan tindakan (transaksi keuangan, meskipun kecil) jika pengguna mengambil tindakan afirmatif langsung di halaman.
Joe Enzminger
1

Solusi Vanila JS:

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

Tidak akan berpartisipasi dalam diskusi intelektual, kode yang bekerja untuk saya untuk menyaring .click()dan .trigger('click')adalah-

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