У jQuery, як я можу визначити між програмним і користувацьким клацанням?


91

Скажімо, у мене визначено обробник кліків:

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

});

Як я можу, в обробнику функцій, визначити, чи подія була запущена програмно, чи користувачем?


Як в програмі відбувається програмне випуск події?
Clayton

5
Навіщо потрібно розрізняти справи?
Damien_The_Unbeliever

@Clayton: $x.click()або $x.trigger('click').
mu занадто короткий

У мене була ситуація з повзунком зображення, який автоматично прокручував зображення, і робив це, викликаючи клацання на правильному елементі навігації, пов’язаному із зображенням. Проблема в тому, що коли користувач натискає навігаційну панель, автоматичне обертання має припинитися.
Касапо

2
Це працює в останніх версіях firefox, chrome та IE9. Чому б не прийняти відповідь нижче з найбільшою кількістю голосів ?? @kevino
OZZIE

Відповіді:


119

Ви можете поглянути на об’єкт події e. Якщо подія була викликана реальним натисканням кнопки, ви будете мати такі речі , як clientX, clientY, pageX, pageYі т.д. всередині eі вони будуть числа; ці цифри пов’язані з положенням миші при спрацьовуванні клацання, але вони, ймовірно, будуть присутні, навіть якщо клацання було ініційовано за допомогою клавіатури. Якщо подія була ініційована до $x.click()цього часу, у вас не буде звичайних значень позицій у e. Ви також можете подивитися на originalEventнерухомість , якої не повинно бути там, якщо подія відбулася $x.click().

Можливо щось подібне:

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

І ось маленька пісочниця, з якою можна пограти: http://jsfiddle.net/UtzND/


4
Це чудово ... Я просто подумав собі, "можливо, події, що запускаються jQuery, не мають інформації про положення миші"! w00t!
Касапо

2
Це можна перемогти у браузерах, які підтримують createEvent. jsfiddle.net/UtzND/26
Джо Ензмінгер

2
@JoeEnzminger так, але чому б ви перемогли власний сценарій, так би мовити ...?
OZZIE

3
Мене турбує сторонній скрипт, що генерує подію кліку, і мій сценарій обробляє її, припускаючи, що її створив користувач (фактичний клік).
Джо Ензмінгер,

2
@JoeEnzminger: Усі ставки припиняються, як тільки ваш код потрапляє в браузер, ви нічого не можете зробити, що не зможе перемогти досить розумна людина. Я думаю, що найкраще, що ви можете зробити, це перевірити купу речей: чи є таке originalEvent? Чи це правильно? Чи є десь координати? Чи узгоджуються координати? Координати всередині #foo? ...
mu занадто короткий

44

Ви можете використовувати додатковий параметр, як зазначено в посібнику для запуску jQuery :

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

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

3
Єдина проблема, яку я бачу в цьому, полягає в тому, що ви не можете розрізнити звичайний клік $x.click(), а .click()абонент повинен чітко сказати вам, що вони підробляють це. Це може бути проблемою, а може і не залежати від того, що задумав Кевін Овоцький.
мю занадто коротке

1
@mu: Я не зовсім розумію вашу різницю між "звичайним" клацанням (користувачем?) та тим, $x.click()що є eventHandler (для кліку користувача, який може бути "нормальним")
Shikiryu

1
Різниця полягає в тому, що один походить від користувача, а інший - від програмного забезпечення. Фальшивий клік може надходити від плагіна чи іншого коду, який не можна змінити, щоб додати зайві аргументи. Я не критикую ваше рішення, лише зазначаю деякі можливі діри.
мю занадто коротке

Хоча mu правильно, і це не спрацює у кожній ситуації, я шукав саме те, дякую! Не знав, що можу передати додатковий параметр як var, але саме це мені потрібно, щоб перевірити "справжні" кліки у складному інтерфейсі, який розглядає деякі "реальні" кліки як програмні. Дякую за неймовірно корисні рішення!
Філ

9

Вже є відповідь на інше запитання.

Як визначити, чи є клацання () клацанням миші або викликане якимсь кодом?

Використовуйте whichвластивість об’єкта події. Це має бути undefinedдля подій, викликаних кодом

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

Приклад JsFiddle - http://jsfiddle.net/interdream/frw8j/

Сподіваюся, це допоможе!


2
Не завжди працює. Наприклад, можна selectбуло б дати e.which==undefinedнавіть за справжню подію.
JNF

5

Я спробував усі вищезазначені рішення, і в моєму випадку нічого не вдалося. Нижче рішення працювало для мене. Сподіваюся, це допоможе і вам.

$(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 Level 3 визначає event.isTrusted. Наразі це підтримується лише в IE9 + та Firefox (на основі моїх тестів. Я також читав (хоча і не ретельно досліджений), що це можна замінити в деяких браузерах і, мабуть, ще не на 100% готове до того, щоб йому дійсно довіряли (на жаль).

Це модифікована версія скрипки @ mu, яка працює на IE та Firefox.


Гарна думка. Я не думаю, що щось буде на 100% твердим. Вам доведеться змішати деякі тести, щоб побачити, чи isTrustedпідтримується та не можна записати. Я думаю, що справжня відповідь залежить від того, чому стоїть це питання, і ми так і не з’ясували, чому.
мю занадто коротке

@mu, я прийшов до цього питання, поставивши подібне, але більш загальне. Мій випадок «чому» полягає в тому, що я хочу переконатись, що виконую лише дію (фінансову операцію, хоч і невелику), якщо користувач здійснив прямі позитивні дії на сторінці.
Joe Enzminger

1

Рішення Vanila js:

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

-1

Я не збираюся брати участь в інтелектуальному обговоренні, коді, який працював для мене для фільтрування, .click()і .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
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.