JQuery передает фокус и нажимает на элемент - PullRequest
11 голосов
/ 03 февраля 2011

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

  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 (это bad ). Когда запускается обработчик click, lastAddressRecord портится.

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

Ответы [ 3 ]

15 голосов
/ 03 февраля 2011

Вот кое-что, что я думаю, работает, основываясь на том факте, что 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;

});

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

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;
});

Единственная проблема заключается в том, что вы не получаете «щелчок» или вкладку, когда вы переключаетесь из окна и переключаетесь обратно. Вы получаете событие фокуса на входе, который имел фокус, но вы не можете определить, является ли это вкладкой или щелчком, потому что это ни то, ни другое.

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

2 голосов
/ 26 ноября 2012

Вы можете использовать метод .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;
});
0 голосов
/ 03 февраля 2011

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

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

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
});
...