JQuery, передающий фокус и щелчок по элементу

Я пытаюсь определить рабочий процесс для точной настройки веб-приложения для ввода данных. Создайте несколько форм адресов на одной веб-странице:

  1. Name___________
     Street_________
     Phone__________

  2. Name___________
     Street_________
     Phone__________

  [...many more...]

Теперь я хотел бы узнать, использует ли пользователь ключ табуляции, чтобы перейти ко второму полю "Имя" (или в любом месте этой записи), или если они используют мышь, чтобы щелкнуть по ней. (Или shift-tab для перемещения в обратном направлении.)

Я установил обработчик для обоих фокусов и нажимаю для полей ввода:

$('input').click(function() { TabulateClick(this) });
$('input').focus(function() { TabulateFocus(this) });

И в обработчике я определяю, на какой адрес работает пользователь, и были ли мы "переключали" записи адреса. (Если фокус был в "Телефон" для первого адреса, и вы нажимаете на поле "Имя" по тому же адресу, что на самом деле не переключает записи, поэтому я не делаю табуляцию.)

    function TabulateClick(field)
    {
         var currentAddressRecord = FindAddress(field);
         if ( lastAddressRecord != currentAddressRecord )
             switchedAddressesWithClick++;
         lastAddressRecord = currentAddress;
    }
    function TabulateFocus(field)
    {
         var currentAddress = FindAddress(field);
         if ( lastAddressRecord != currentAddressRecord )
             switchedAddressesWithTab++;
         lastAddressRecord = currentAddress;
    }

Моя проблема заключается в том, что при щелчке мыши в поле событие focus запускает первую таблицу с ложным switchedAddressesWithTab и меняет currentAddress (Плохо). Когда выполняется обработчик click, lastAddressRecord испорчен.

Есть ли способ внутри обработчика focus знать, что на этом же объекте есть ожидающее событие click? Или в обработчике click, чтобы знать, что он был ранее просто обработан focus?

Ответ 1

Здесь что-то, что я думаю, работает на основе того факта, что mousedown происходит до фокуса. См. демо.

var lastClick = null;
$('input').mousedown(function(e) {
  lastClick = e.target;
}).focus(function(e){
    if (e.target == lastClick) {
      console.log('click');
    } else {
      console.log('tab');    
    }
    lastClick = null;

});

Чтобы исправить ошибку, обнаруженную Josiah, я изменил свой код на ниже. См. демо.

var lastFocusedElement = null;
var isClick = false;
$('input').mousedown(function(e) {     
     isClick= true;
}).focus(function(e){

    // To prevent focus firing when element already had focus
    if (lastFocusedElement != e.target) {
        if (isClick) {
          console.log('click ----');
        } else {
          console.log('tab -----');    
        }
        lastFocusedElement = e.target;
        isClick = false;
    }
});

$(document.body).focus(function(){
  lastFocusedElement = document.body;
});

Одна проблема заключается в том, что вы не получаете 'click' или вкладку, когда вы переключаетесь от окна и переключаетесь обратно. Вы получаете фокусное событие на вкладке с фокусом, но вы не можете определить, есть ли вкладка или щелчок, потому что это тоже.

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

Ответ 2

Вы можете использовать метод . on() в jQuery. Вот еще один способ привязать оба события к одному элементу.

var hasClicked = false;
$('.myinputfield').on('mousedown : click',function(e){
     if (e.type == 'mousedown') {
        // execute code
        hasClicked = true;
     }
     if(e.type == 'focus' && !hasClicked) {
        //execute code
        console.log(e.type)
     }
     hasClicked = false;
});

Ответ 3

Просто привяжите фокус, а затем проверьте событие, чтобы увидеть, есть ли e.which == 9 // tab.

Моя оригинальная идея не сработала (спасибо @Juan). Использование сочетания событий должно привести вас туда, где вы хотите быть. Если пользователь нажимает на текстовое поле, последнее нажатие клавиши не будет вкладом. Все входы просматривают и сохраняют последний key code, чтобы перейти к событию фокуса. вот скрипка

var lastKeyCode = 0;
$('input').focus(function(e) {
    if(lastKeyCode == 9)
         // tabbed into field
    else
         // clicked into field
}).keydown(function(e){
    if(e.which == 9) // added timeout to clear lastkeypress
        setTimeout(function(){lastKeyPress = 0}, 50);
    lastKeyPress = e.which; // store last key code
});