2011-02-03 11 views
11

Tôi đang cố gắng xác định quy trình làm việc để tinh chỉnh ứng dụng web nhập dữ liệu. Hình ảnh một số biểu mẫu địa chỉ trên một trang web duy nhất:jQuery giao cả hai tiêu điểm và nhấp vào một phần tử

1. Name___________ 
    Street_________ 
    Phone__________ 

    2. Name___________ 
    Street_________ 
    Phone__________ 

    [...many more...] 

Bây giờ tôi muốn biết liệu người dùng có sử dụng phím tab để đến trường "Tên" thứ hai (hoặc bất kỳ nơi nào trong hồ sơ đó) hay không nếu họ đang sử dụng chuột để click vào nó. (Hoặc Shift-Tab để di chuyển theo hướng ngược lại.)

tôi đã thiết lập một handler trên cả hai lấy nét và bấm cho các lĩnh vực đầu vào:

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

Và trong xử lý, tôi xác định giải quyết cho người sử dụng là làm việc và liệu chúng tôi đã "chuyển đổi" các bản ghi Địa chỉ. (Nếu trọng tâm là trong "Điện thoại" cho địa chỉ đầu tiên, và bạn click vào trường "Tên" trong cùng địa chỉ, đó là không thực sự chuyển đổi hồ sơ, vì vậy tôi không chia loại đó.)

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

Vấn đề của tôi là khi tôi bấm chuột vào trường focus sự kiện cháy đầu tiên lập bảng giả switchedAddressesWithTab và thay đổi hiện tạiĐịa chỉ (đó là xấu). Khi trình xử lý click chạy, lastAddressRecord bị hỏng.

Có cách nào bên trong trình xử lý focus để biết rằng có sự kiện click đang chờ xử lý trên cùng một đối tượng không? Hoặc trong trình xử lý click để biết rằng nó đã được xử lý trước đây bởi focus?

Trả lời

15

Dưới đây là một cái gì đó mà tôi nghĩ rằng tác phẩm dựa trên thực tế rằng mousedown xảy ra trước khi tập trung. Xem demo.

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; 

}); 

Để khắc phục lỗi do Josiah phát hiện, tôi đã thay đổi mã của mình thành bên dưới. Xem demo.

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

Một vấn đề là bạn không nhận được 'nhấp chuột' hoặc tab khi bạn chuyển ra khỏi cửa sổ và quay lại. Bạn nhận được một sự kiện tập trung vào đầu vào đã tập trung, nhưng bạn không thể xác định xem đó là một tab hay một nhấp chuột, bởi vì nó không phải là.

Tôi nghĩ rằng đây là gần nhất bạn sẽ nhận được, tôi sẽ thử điều này trên trang của bạn và xem liệu hành vi đó có đủ tốt hay không.

+0

@Juan - kể từ khi chúng tôi tham gia QA ngay hôm nay, khi bạn duyệt qua tất cả các trường đến cơ thể, sau đó nhấp vào một bảng điều khiển, nhấp vào tab –

+0

@Josiah: Tốt, tôi không hiểu tại sao nó xảy ra mặc dù .. Tôi đoán chúng tôi đã cung cấp OP với hai cách làm việc hầu hết thời gian, vẫn còn đầu tư thêm 2 phút cho điều này mặc dù –

+0

@Juan - yah cảm ơn vì đã nói với tôi về chi tiêu hoàn toàn nhiều thời gian hơn tôi dự đoán về câu hỏi này;) làm, dang phát triển. –

0

Chỉ cần gắn tiêu điểm và sau đó kiểm tra sự kiện để xem liệu e.which == 9 // tab.

Ý tưởng ban đầu của tôi không hoạt động (nhờ @Juan). Sử dụng sự kết hợp các sự kiện sẽ giúp bạn có được nơi bạn muốn. Nếu người dùng nhấp vào hộp văn bản, lần nhấn phím cuối cùng sẽ không phải là tab. Tất cả đầu vào đều đang xem và lưu trữ mã khóa cuối cùng để chuyển đến sự kiện lấy nét. here is the fiddle

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

mmm, rất thú vị, được thử nghiệm này? –

+0

@Josiah: Tôi không nghĩ rằng công trình này - Trong FF tôi nhận được không xác định ngay cả khi tôi tab vào lĩnh vực này. –

+0

Không hoạt động: http://jsfiddle.net/3py9V/. Nếu bạn đề xuất điều gì đó chưa được kiểm tra, bạn nên đề cập đến câu trả lời của bạn là một đề xuất chưa được kiểm tra –

2

Bạn có thể sử dụng phương thức .on() trong jQuery. Đây là một cách khác để liên kết cả hai sự kiện trên cùng một phần tử.

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