Проверить, инициировано ли событие человеком

141

У меня есть обработчик, прикрепленный к событию, и я хотел бы, чтобы он выполнялся только в том случае, если он запускается человеком, а не методом trigger (). Как отличить?

Например,

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

$('.checkbox').trigger('change'); //doesn't alert
Дзиамид
источник

Ответы:

214

Ты можешь проверить e.originalEvent : если он определен, щелчок человеческий:

Посмотрите на скрипку http://jsfiddle.net/Uf8Wv/

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

мой пример на скрипке:

<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();
});
Никола Пелучетти
источник
1
@Nicola Это где-нибудь задокументировано?
Шиме Видас
@Sime не знаю, но думаю, что это стандартно. смотрите здесь: api.jquery.com/category/events/event-object
Никола Пелучетти
@Nicola: Понятно, это jQuery. jQuery сохраняет исходный объект события внутри этого свойства. Кстати, что ты имеешь в виду, что не знаешь? Вы только что предоставили ссылку на документацию:)
Шиме Видас
1
Похоже, вы тоже можете использоватьevent.isTrigger
avoliva
1
@Anurag, я только что столкнулся с той же проблемой. Похоже, что jQuery заполняется, originalEventкогда событие запускается DOM.click(), но вы можете использовать $($("#try")[0]).click();, что неуклюже, но работает.
Дэниел Гарретт,
19

Более прямым, чем выше было бы:

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

$('.checkbox').trigger('change'); //doesn't alert
Кеннет Спенсер
источник
Это лучший ответ. Для объяснения см .: stackoverflow.com/questions/10704168/…
jaredjacobs
3
Хотя это заманчиво и, вероятно, удобно на практике, обратите внимание, что разработчики jQuery не хотят переходить isTriggerна публичный API на данный момент .
Джон
7

Я думаю, что единственный способ сделать это - передать дополнительный параметр при triggerвызове в соответствии с документацией .

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

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

Пример: http://jsfiddle.net/wG2KY/

Detaylor
источник
1
вы можете проверить свойство originalEvent объекта события: если событие не происходит от щелчка, оно не определено
Никола Пелучетти
1
По какой-то причине event.originalEvent у меня не работал (просто продолжал возвращать 1) при использовании обработчика щелчка Zepto. Итак, я попробовал решение выше. Работал как шарм.
Larrydx
7

Принятый ответ у меня не сработал. Прошло 6 лет, и с тех пор jQuery сильно изменился.

Например, event.originalEventвсегда возвращается trueс jQuery 1.9.x. Я имею в виду, что объект существует всегда, но содержание другое.

Те, кто использует более новые версии jQuery, могут попробовать это. Работает в Chrome, Edge, IE, Opera, FF

if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
    //Hey hooman it is you
}
Ergec
источник
3

В настоящее время большинство браузеров поддерживают event.isTrusted :

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

Из документов :

IsTrusted только для чтения свойства Eventинтерфейса является , Boolean что это верно , когда событие было порождается действием пользователя, и ложно , когда событие было создано или изменено путем сценарием или послано через EventTarget.dispatchEvent () .

фелипсмартинс
источник
0

Если у вас есть контроль над всем вашим кодом, никаких инопланетных вызовов, $(input).focus()кроме setFocus().

Для меня использование глобальной переменной - правильный способ.

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

Если какой-то инопланетянин все же захочет позвонить $(input).focus()с другой планеты. Удачи или проверьте другие ответы

vanduc1102
источник
Это только мешает людям звонить setFocus()- это не мешает людям запускать событие фокусировки. Если setFocus()вообще не писать, то люди не смогут его назвать, поэтому я не вижу в этом пользы. На самом деле, люди все еще могли позвонить $('input').focus()и пройти.
Роб
вау, впервые у меня кто-то комментирует сразу после того, как я ответил на вопрос, я
обновлю
Если вы работаете в закрытой среде без каких-либо других / сторонних сценариев, это сработает в идеальном мире. Однако большинство практических приложений предназначены для клиентских сайтов, к которым добавлены всевозможные плагины и скрипты, которые вполне могут вызвать это внимание. Одна вещь, которая может помочь в этом, - это заключить ваш код (и любой код, который должен вызывать эту функцию) в функцию с ограниченной областью видимости, подобную этой: (function(){/*your code here*/})();Это защитит функцию setFocus от вызова, а логическое значение - от изменения внешними скриптами.
Xandor
-1

Вы можете использовать onmousedown для обнаружения щелчка мыши и вызова trigger ().

боатенг
источник
Я могу не работать по следующему сценарию: Иногда можно выбрать элементы страницы с помощью клавиши Tab. Например, если я установил таким образом флажок, я могу поставить / снять отметку с помощью клавиши пробела. Или даже откройте раскрывающийся список с помощью клавиши со стрелкой вниз.
Диего Фаверо
-1

Я бы подумал о возможности, когда вы проверяете положение мыши, например:

  • Нажмите
  • Получить позицию мыши
  • Перекрывает координаты кнопки
  • ...
Люк
источник
Я могу не работать по следующему сценарию: Иногда можно выбрать элементы страницы с помощью клавиши Tab. Например, если я установил таким образом флажок, я могу поставить / снять отметку с помощью клавиши пробела. Или даже откройте раскрывающийся список с помощью клавиши со стрелкой вниз.
Диего Фаверо