Различать событие фокусировки, вызванное клавиатурой/мышью
Я использую jquery ui autocomplete и хочу расшифровать события фокуса, вызванные взаимодействием клавиатуры и взаимодействием с мышью. Как я могу это сделать?
$('input').autocomplete({
source: function(request, response) {
...
},
focus: function(event, ui) {
// If focus triggered by keyboard interaction
alert('do something');
// If focus event triggered by mouse interaction
alert('do something else');
}
});
Спасибо
Ответы
Ответ 1
Единственный способ, которым я могу это сделать, - это прослушивание обработчиком событий keypress
и click
, а также включение/выключение булевого флага. Затем на обработчике focus
вашего ввода вы можете просто проверить, что такое значение вашего флага, и оттуда.
Возможно, что-то вроде
var isClick;
$(document).bind('click', function() { isClick = true; })
.bind('keypress', function() { isClick = false; })
;
var focusHandler = function () {
if (isClick) {
// clicky!
} else {
// tabby!
}
}
$('input').focus(function() {
// we set a small timeout to let the click / keypress event to trigger
// and update our boolean
setTimeout(focusHandler,100);
});
Взбитый небольшой рабочий прототип на jsFiddle (вам не нравится только этот сайт?). Проверьте, хотите ли вы.
Конечно, это все работает с событием focus
на <input>
, но обработчик focus
на автозаполнении работает одинаково.
setTimeout
представит немного отставания, но в 100 мс он может быть незначительным, исходя из ваших потребностей.
Ответ 2
Фактически вы должны определить это из события-объекта, который передается в фокус-событие. В зависимости от структуры кода это может быть другим, но обычно существует свойство originalEvent
, которое может быть вложено в некоторую глубину. Осмотрите объект event
более подробно, чтобы определить правильный синтаксис. Затем выполните проверку на mousenter
или keydown
с помощью регулярного выражения. Что-то вроде этого:
focus: function(event, ui){
if(/^key/.test(event.originalEvent.originalEvent.type)){
//code for keydown
}else{
//code for mouseenter and any other event
}
}
Ответ 3
Самый простой и элегантный способ, который я нашел для этого, - использовать What Input?" library. Он крошечный (~ 2K minified) и дает вам доступ к типу события как в сценариях:
if (whatInput.ask() === 'mouse') {
// do something
}
... а также (с помощью одного атрибута данных, который он добавляет к стилю документа body
):
[data-whatinput="mouse"] :focus,
[data-whatinput="touch"] :focus {
// focus styles for mouse and touch only
}
Мне особенно нравится тот факт, что, когда вам просто нужно другое визуальное поведение для мыши/клавиатуры, это позволяет сделать это в таблице стилей (где она действительно принадлежит), а не через некоторый хакерский бит проверки событий Javascript (хотя конечно, если вам нужно сделать что-то, что не просто чисто визуально, прежний подход позволит вам обрабатывать его в Javascript).
Ответ 4
Первое, что приходит в голову, это то, что вы можете найти положение мыши и проверить, не находится ли внутри этого элемента элемент
Используйте это, чтобы сохранить позицию элемента:
var input = $('#your_autocompleted_element_id'),
offset = input.offset(),
input_x = offset.top,
input_y = offset.left,
input_w = input.outerWidth(),
input_h = input.outerHeight();
Затем используйте это, чтобы найти абсолютное положение мыши в окне:
var cur_mx, cur_my;
$(document).mousemove(function(e){
cur_mx = e.pageX;
cur_my = e.pageY;
});
Затем в настройке автозаполнения:
focus: function(event, ui) {
// mouse is doing the focus when...
// mouse x is greater than input x and less than input x + input width
// and y is greater than input y and less than input y + input height
if (cur_mx >= input_x && cur_mx <= input_x + input_w && cur_my >= input_y && cur_my <= input_y + input_h) {
// do your silly mouse focus witchcraft here
} else {
// keyboard time!
}
}