2009-03-31 38 views
21

Tôi muốn trình duyệt hoạt động như thể người dùng đã nhấn phím Tab khi họ nhấp vào một cái gì đó. Trong xử lý nhấp chuột Tôi đã thử các phương pháp sau đây:Mô phỏng nhấn phím bằng cách sử dụng JavaScript

var event = document.createEvent('KeyboardEvent'); 
event.initKeyEvent("keypress", true, true, null, false, false, false, false, 9, 0); 
this.input.focus()[0].dispatchEvent(event); 

Và jQuery:

this.input.focus().trigger({ type : 'keypress', which : 9 }); 

... mà tôi mất từ ​​here.

Cách tiếp cận đầu tiên có vẻ là đặt cược tốt nhất, nhưng không hoàn toàn hiệu quả. Nếu tôi thay đổi hai tham số cuối cùng thành 98, 98, thực sự, một 'b' được nhập vào hộp nhập liệu. Nhưng 9, 0 và 9, 9 (cựu trong đó tôi mất ngay từ trang web MDC) đều cung cấp cho tôi những sai sót trong firebug dưới FF3:

Permission denied to get property XULElement.popupOpen 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.overrideValue 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to set property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Tôi đã nghe như vậy (không có định nghĩa rõ ràng về các sự kiện 'như vậy' là 'không đáng tin cậy', điều này có thể giải thích những lỗi này.

Cách tiếp cận thứ hai gây ra bất kỳ giá trị nào tôi đặt dưới dạng sự kiện.được chuyển thành sự kiện. Nhưng không có hiệu lực (ngay cả khi tôi sử dụng 98 thay vì 9, không có 'b' được nhập vào hộp.) Tôi cố gắng thiết lập event.data trong đối tượng tôi đang đi qua, nó kết thúc không xác định khi sự kiện được kích hoạt. Nội dung sau là mã tôi đang sử dụng để xem:

$('#hi').keypress(function(e) { 
    console.log(e); 
}); 

Có ý tưởng nào khác không?

+0

Ông muốn gì để gọi? Bạn đang cố gắng chuyển chúng sang đầu vào tiếp theo? – hunter

+0

Có. Nhưng "đầu vào" tiếp theo không nhất thiết là đầu vào hoặc yếu tố tự nhiên khác. Cũng không nhất thiết phải là tabstopped không tự nhiên (tức là, $ ("[tabindex]")). Tab nhấn vật lý (hoặc phím shift +) thực hiện chính xác những gì tôi muốn ... – Kev

+0

Cảm ơn vì điều này. Tôi chỉ quan tâm đến ví dụ mã đầu tiên của câu hỏi của bạn, điều này thực sự đã giúp :) –

Trả lời

4

Giải pháp mà tôi đã kết thúc là tạo div "lấy nét tiêu điểm" div (với tabindex = -1 - có thể lấy tiêu điểm nhưng không thể được tab vào ban đầu) ở hai bên của khu vực mà tôi muốn quản lý tập trung theo cách thủ công. Sau đó, tôi đặt một người nghe sự kiện sôi nổi để tập trung và làm mờ toàn bộ khu vực. Khi bất kỳ tiêu điểm nào xuất hiện trên vùng, các giá trị tab được thay đổi thành -1 và khi có bất kỳ hiệu ứng nhòe nào, chúng thay đổi thành 0. Điều này có nghĩa là trong khi tập trung vào khu vực, bạn có thể tab hoặc shift-tab ra khỏi vùng đó và kết thúc chính xác trên các phần tử trang khác hoặc các phần tử giao diện người dùng trình duyệt, nhưng ngay khi bạn lấy nét ra khỏi đó, các tiêu điểm tập trung trở thành tabbable, và tập trung họ thiết lập vùng thủ công một cách chính xác và shunt tập trung vào phần tử ở cuối, như thể bạn đã nhấp vào một đầu hoặc đầu kia của khu vực thủ công.

1

Thực ra, tôi đoán có một cách, ngay cả khi đó là PITA chính. Tôi có thể chắc chắn rằng mọi phần tử, ngay cả khi một tab-stop tự nhiên, có một Xtabindex, bằng cách nào đó theo thứ tự thích hợp mặc dù tôi sẽ rơi vào các widget của người khác và sử dụng jQuery để thêm chúng sau khi thực tế, thay vì có thể chỉ định nó ngay trong HTML hoặc mã xây dựng ban đầu khác. Sau đó, toàn bộ hình thức của tôi sẽ có một tabindex thực sự. Trong khi nó có tiêu điểm, nó sẽ hấp thụ các phím bấm, và nếu chúng là tab hoặc shift + tab, di chuyển tiêu điểm giả dựa trên Xtabindex. Nếu tab được nhấn vào phần tử cuối cùng (hoặc shift + trên đầu tiên) trong biểu mẫu, nó sẽ không nuốt phím tắt, do đó cho phép trình duyệt tập trung đúng vào các phần tử giao diện trang hoặc trình duyệt khác bên ngoài biểu mẫu bằng bàn phím.

Tôi chỉ có thể đoán những loại tác dụng phụ không mong muốn mà phương pháp này sẽ giới thiệu.

Thực ra, nó thậm chí không phải là giải pháp, bởi vì tôi vẫn không thể giả mạo một tab trên phần tử cuối cùng bằng cách sử dụng nó.

+0

http: // lists .whatwg.org/htdig.cgi/whatwg-whatwg.org/2008-December/017980.html đưa ra một điểm thú vị: "Nhưng sau đó điều gì xảy ra nếu tác nhân người dùng không thực hiện việc sử dụng chu trình mà thay vào đó sử dụng quản lý tập trung định hướng , giống như nhiều điện thoại? " – Kev

3

Đây là giải pháp tôi sử dụng trên ứng dụng web của chúng tôi cho hai điều khiển tùy chỉnh, lịch sổ pop-up và chọn trọng lượng đơn vị pop-up/giá trị (nhấn vào hộp văn bản bật lên một div với hai Selects)

function tab_focus(elem) 
    var fields = elem.form.getElements() 
    for(var i=0;i<fields.length;i++) { 
    if(fields[i].id == elem.id){ 
     for(i=i+1;i<fields.length;i++){ 
     if(fields[i].type != 'hidden'){ 
      fields[i].focus() 
      return  
     } 
     } 
     break; 
    } 
    } 
    elem.form.focusFirstElement(); 
} 

Điều này đang sử dụng khung Prototype và dự kiến ​​phần tử mở rộng (ví dụ: $ ('thing_id')) làm thông số của nó.

Nó lấy dạng phần tử thuộc về và lặp qua các phần tử của biểu mẫu cho đến khi nó tìm thấy chính nó.

Sau đó, tìm phần tử đầu tiên sau phần tử không bị ẩn và chuyển tiêu điểm đó.

Nếu không có phần tử nào sau nó trong biểu mẫu, nó sẽ di chuyển tiêu điểm trở lại phần tử đầu tiên trong biểu mẫu. Thay vào đó, tôi có thể tìm thấy biểu mẫu tiếp theo trên trang thông qua document.forms, nhưng hầu hết các trang của chúng tôi đều sử dụng một biểu mẫu duy nhất.

+0

Vấn đề là, một số yếu tố giao diện người dùng có thể tập trung của tôi không phải là các phần tử biểu mẫu, vì chúng là các tiện ích tùy chỉnh. – Kev

+1

Đối với người dùng jquery, hãy thay thế dòng đầu tiên của hàm này bằng: var fields = $ ('form') [0]; Để lặp qua các phần tử biểu mẫu. – eniac

0

Tôi nghĩ rằng các lỗi đó là từ tự động hoàn tất. Bạn có thể có thể tắt chúng đi bằng cách thiết lập, trước khi bạn cử sự kiện này, các autocomplete gán cho 'tắt'

setAttribute('autocomplete','off') 
1

Tôi tạo ra một simple jQuery plugin mà không giải quyết vấn đề này. Nó sử dụng bộ chọn ': tabbable' của jQuery UI để tìm phần tử 'tabbable' tiếp theo và chọn nó.

sử dụng Ví dụ:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){ 
    $.tabNext(); 
    return false; 
}); 
Các vấn đề liên quan