Как в jQuery отличить программный щелчок от щелчка пользователя?

91

Скажем, у меня определен обработчик кликов:

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

});

Как я могу в обработчике функции определить, было ли событие запущено программно или пользователем?

Кевин Овоки
источник
Как программа запускает событие программно?
Clayton
5
Зачем нужно различать случаи?
Damien_The_Unbeliever
@ Клейтон: $x.click()или $x.trigger('click').
mu слишком короткий
У меня была ситуация с изображением-слайдером, который автоматически прокручивал изображения, и делал это, вызывая щелчки по правильному элементу навигации, связанному с изображением. Проблема в том, что когда пользователь нажимает на навигацию, автоматическое вращение должно прекращаться.
Kasapo 08
2
Это работает в последних версиях Firefox, Chrome и IE9. Почему бы не принять ответ, набравший наибольшее количество голосов? @kevino
OZZIE

Ответы:

120

Вы можете взглянуть на объект события 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/

mu слишком короткий
источник
4
Это потрясающе ... Я просто подумал: «Может быть, события, запускаемые jQuery, не имеют информации о положении мыши»! w00t!
Kasapo 08
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()абонент должен явно сказать, что они притворяются. Это может быть или не быть проблемой в зависимости от того, что задумал Кевин Овоки.
mu слишком короткий
1
@mu: Я не совсем понимаю вашу разницу между «обычным» щелчком (пользователь?) и $x.click()обработчиком событий (для пользовательского щелчка, который может быть «нормальным»)
Шикирю
1
Разница в том, что один исходит от пользователя, а другой - от программного обеспечения. Фальшивый щелчок может исходить из плагина или другого кода, который нельзя изменить для добавления дополнительных аргументов. Я не критикую ваше решение, просто отмечу некоторые возможные дыры.
mu слишком короткий
Хотя mu верен, и это не сработает в каждой ситуации, это было именно то, что я искал, спасибо! Не знал, что могу передать дополнительный параметр, например var, но это именно то, что мне нужно для проверки «реальных» кликов в сложном пользовательском интерфейсе, который рассматривает некоторые «настоящие» клики как программные. Спасибо за оба невероятно полезных решения!
Фил
9

Уже есть ответ на другой вопрос.

Как определить, является ли click () щелчком мыши или запускается каким-либо кодом?

Используйте whichсвойство объекта события. Это должно быть undefinedдля событий, запускаемых кодом

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

Пример JsFiddle - http://jsfiddle.net/interdream/frw8j/

Надеюсь, это поможет!

Swanidhi
источник
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>

GSB
источник
4

DOM Level 3 определяет event.isTrusted. В настоящее время это поддерживается только в IE9 + и Firefox (на основе моих тестов. Я также читал (хотя и не изучал полностью), что его можно переопределить в некоторых браузерах, и, вероятно, он еще не на 100% готов к тому, чтобы действительно доверять (к сожалению).

Это модифицированная версия скрипки @ mu, которая работает в IE и Firefox.

Джо Энцмингер
источник
Хорошая точка зрения. Я не думаю, что что-то будет на 100% надежным. Вам придется смешать некоторые тесты, чтобы увидеть, isTrustedподдерживается ли он, а не записывается ли. Я думаю, что настоящий ответ зависит от того, почему стоит этот вопрос, и мы так и не узнали почему.
mu слишком короткое
@mu, я пришел к этому вопросу после того, как задал похожий, но более общий вопрос. Мой случай «почему» заключается в том, что я хочу убедиться, что я выполняю действие (финансовую транзакцию, хотя и небольшую) только в том случае, если пользователь предпринял прямое положительное действие на странице.
Джо Энцмингер
1

Решение Vanila js:

document.querySelector('button').addEventListener('click', function (e){
    if(e.isTrusted){
        // real click.
    }else{
        // programmatic click
    }
});
Абхишек
источник
-1

Не собираюсь участвовать в интеллектуальной дискуссии, код , который работал для меня фильтр .click()и .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
    }
});
Саху В Кумар
источник