Periksa apakah acara dipicu oleh manusia

140

Saya memiliki handler yang melekat pada suatu peristiwa dan saya ingin itu dijalankan hanya jika dipicu oleh manusia, dan bukan oleh metode pemicu (). Bagaimana saya membedakannya?

Sebagai contoh,

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

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

Jawaban:

212

Anda dapat memeriksa e.originalEvent: jika didefinisikan klik adalah manusia:

Lihatlah biola http://jsfiddle.net/Uf8Wv/

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

contoh saya di biola:

<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
sumber
1
@Nicola Apakah ini didokumentasikan di mana saja?
Šime Vidas
@Sime saya tidak tahu, tapi saya pikir itu standar. lihat di sini: api.jquery.com/category/events/event-object
Nicola Peluchetti
@Nicola, begitu, ini masalah jQuery. jQuery menyimpan objek acara asli di dalam properti ini. Btw, apa maksudmu kamu tidak tahu? Anda baru saja memberikan tautan ke dokumentasi:)
Šime Vidas
1
Sepertinya Anda juga dapat menggunakanevent.isTrigger
avoliva
1
@Anagag, saya mengalami masalah yang sama tadi. Sepertinya jQuery terisi originalEventketika acara dipicu oleh DOM.click(), tetapi Anda dapat menggunakan $($("#try")[0]).click();, yang kikuk, tetapi berfungsi.
Daniel Garrett
19

Lebih lurus daripada di atas adalah:

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

$('.checkbox').trigger('change'); //doesn't alert
Kenneth Spencer
sumber
Ini jawaban terbaik. Untuk penjelasan, lihat: stackoverflow.com/questions/10704168/…
jaredjacobs
3
Meskipun ini menggoda dan mungkin nyaman dalam praktiknya, perhatikan bahwa pengembang jQuery tidak ingin lulus isTriggerke API publik saat ini .
Jon
7

Saya pikir satu-satunya cara untuk melakukan ini adalah dengan memasukkan parameter tambahan pada triggerpanggilan sesuai dokumentasi .

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

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

Contoh: http://jsfiddle.net/wG2KY/

detaylor
sumber
1
Anda dapat memeriksa properti orisinalnya. Objek objek acara: jika acara tidak berasal dari klik, itu tidak ditentukan
Nicola Peluchetti
1
Entah mengapa event.originalEvent tidak bekerja untuk saya (hanya terus mengingat 1) saat menggunakan pawang 'klik' dari Zepto. Jadi saya mencoba solusi di atas. Bekerja seperti pesona.
Larrydx
7

Jawaban yang diterima tidak berhasil untuk saya. Sudah 6 tahun dan jQuery telah banyak berubah sejak saat itu.

Misalnya event.originalEventkembali selalutrue dengan jQuery 1.9.x. Maksud saya objek selalu ada tetapi konten berbeda.

Mereka yang menggunakan versi jQuery yang lebih baru dapat mencoba yang ini. Bekerja di Chrome, Edge, IE, Opera, FF

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

Saat ini sebagian besar browser mendukung event.isTrusted :

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

Dari dokumen :

The isTrusted read-only properti dari Eventantarmuka adalah Boolean yang benar ketika acara ini dihasilkan oleh tindakan pengguna, dan palsu ketika acara ini dibuat atau dimodifikasi oleh script atau dikirim melalui EventTarget.dispatchEvent () .

felipsmartins
sumber
0

Anda dapat menggunakan onmousedown untuk mendeteksi panggilan klik vs pemicu ().

boateng
sumber
Saya mungkin tidak bekerja pada skenario berikut: Terkadang dimungkinkan untuk memilih elemen halaman menggunakan tombol Tab. Misalnya, jika saya telah memilih dengan cara ini kotak centang, saya dapat mencentang / menghapus centang menggunakan tombol spasi. Atau bahkan buka drodpdown menggunakan tombol panah bawah.
Diego Favero
0

Saya akan memikirkan kemungkinan di mana Anda memeriksa posisi mouse, seperti:

  • Klik
  • Dapatkan posisi mouse
  • Tumpang tindih dengan tombol
  • ...
Luke
sumber
Saya mungkin tidak bekerja pada skenario berikut: Terkadang dimungkinkan untuk memilih elemen halaman menggunakan tombol Tab. Misalnya, jika saya telah memilih dengan cara ini kotak centang, saya dapat mencentang / menghapus centang menggunakan tombol spasi. Atau bahkan buka drodpdown menggunakan tombol panah bawah.
Diego Favero
0

Jika Anda memiliki kendali atas semua kode Anda, tidak ada panggilan asing $(input).focus()selain setFocus().

Menggunakan variabel global adalah cara yang benar bagi saya.

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

Jika beberapa alien masih ingin menelepon $(input).focus()dari planet lain. Semoga beruntung atau periksa jawaban lain

vanduc1102
sumber
Ini hanya mencegah orang menelepon setFocus()- itu tidak mencegah orang memicu acara fokus. Tidak menulis setFocus()sama sekali juga akan mencegah orang menyebutnya, jadi saya tidak melihat manfaatnya. Bahkan, orang masih bisa menelepon $('input').focus()dan meneruskannya.
Rob
wow, pertama kali saya memiliki komentar seseorang tepat setelah saya menjawab pertanyaan, saya akan memperbarui jawabannya
vanduc1102
Jika Anda bekerja di lingkungan tertutup tanpa skrip pihak ketiga lainnya, ini akan bekerja di dunia yang sempurna. Namun sebagian besar aplikasi praktis adalah untuk situs klien yang memiliki semua jenis plugin dan skrip yang ditambahkan kepada mereka yang mungkin bisa disebut fokus itu. Satu hal yang mungkin membantu ini adalah membungkus kode Anda (dan kode apa pun yang perlu memanggil fungsi itu) dalam fungsi (function(){/*your code here*/})();lingkup seperti ini: Ini akan membuat fungsi setFocus aman dari pemanggilan dan boolean agar tidak diubah oleh skrip luar.
Xandor