Làm cách nào để đặt tiêu điểm bàn phím cho DIV và đính kèm các trình xử lý sự kiện bàn phím vào đó?


83

Tôi đang xây dựng một ứng dụng mà tôi muốn có thể nhấp vào hình chữ nhật được đại diện bởi DIV, sau đó sử dụng bàn phím để di chuyển DIV đó bằng cách liệt kê các sự kiện trên bàn phím.

Thay vì sử dụng trình xử lý sự kiện cho các sự kiện bàn phím đó ở cấp tài liệu, tôi có thể nghe các sự kiện bàn phím ở cấp DIV, có lẽ bằng cách đặt tiêu điểm bàn phím cho nó?

Đây là một mẫu đơn giản để minh họa vấn đề:

<html>
<head>
</head>
<body>

<div id="outer" style="background-color:#eeeeee;padding:10px">
outer

   <div id="inner" style="background-color:#bbbbbb;width:50%;margin:10px;padding:10px;">
   want to be able to focus this element and pick up keypresses
   </div>
</div>

<script language="Javascript">

function onClick()
{
    document.getElementById('inner').innerHTML="clicked";
    document.getElementById('inner').focus();

}

//this handler is never called
function onKeypressDiv()
{
    document.getElementById('inner').innerHTML="keypress on div";
}

function onKeypressDoc()
{
    document.getElementById('inner').innerHTML="keypress on doc";
}

//install event handlers
document.getElementById('inner').addEventListener("click", onClick, false);
document.getElementById('inner').addEventListener("keypress", onKeypressDiv, false);
document.addEventListener("keypress", onKeypressDoc, false);

</script>

</body>
</html>

Khi nhấp vào DIV bên trong, tôi cố gắng đặt tiêu điểm cho nó, nhưng các sự kiện bàn phím tiếp theo luôn được chọn ở cấp tài liệu, không phải trình nghe sự kiện cấp DIV của tôi.

Tôi có cần thực hiện khái niệm lấy nét bàn phím dành riêng cho ứng dụng không?

Tôi nên thêm Tôi chỉ cần cái này để hoạt động trong Firefox.



1
Không hẳn là một bản dupe - nó đã hỏi khoảng hai năm trước, và đây là câu hỏi làm thế nào để nhận các sự kiện bàn phím trên các phần tử tùy ý, thay vì sử dụng focus()hàm.
Paul Dixon

Câu trả lời:


165

Đã sắp xếp - Tôi đã thêm thuộc tính tabindex vào DIV mục tiêu, ví dụ: khiến nó nhận các sự kiện bàn phím

<div id="inner" tabindex="0">
    this div can now have focus and receive keyboard events
</div>

Thông tin thu thập được từ http://www.w3.org/WAI/GL/WCAG20/WD-WCAG20-TECHS/SCR29.html


6
Ngoài ra, nếu bạn không muốn div có đường viền màu xanh lam khi nó được lấy nét, bạn có thể tạo kiểu cho nó outline: 0px solid tranparent;. Xem: stackoverflow.com/a/2260788/402807
AlcubierreDrive

4
Hoặc thiết lập tabindex="-1", điều đó cũng sẽ ngăn nó nhận được đường viền chấm.
troglobit,

Tôi không thể làm cho điều này hoạt động trong Chrome 60 và FF 54. Và IE11 thực hiện đúng một cách kỳ diệu ngay cả khi không có tabindex. Câu trả lời này có lỗi thời không?
jlh

Điều này không hoạt động đối với tôi trong Firefox hiện tại. Trình duyệt xử lý đầu vào bàn phím. Tương tự cho fiddle.
Kwebble

1
loại bỏ outlinekhông thể truy cập được. nếu bạn không thích hình thức của nó, tôi khuyên bạn nên đưa ra một số dấu hiệu cho thấy thị giác khác rằng nguyên tố này là tập trung trước khi loại bỏ cácoutline
sleeparrow

5

Câu trả lời của Paul hoạt động tốt, nhưng bạn cũng có thể sử dụng contentEditable, như thế này ...

document.getElementById('inner').contentEditable=true;
document.getElementById('inner').focus();

Có thể thích hợp hơn trong một số trường hợp.


6
Nếu bạn làm điều này, Chrome 17 sẽ đặt con trỏ vào phần tử trên tiêu điểm và bạn có thể nhập nội dung trên phần tử. Tôi không khuyên bạn nên điều này.
Seppo Erviälä

1
@Seppo, đó là một điểm tốt. Nếu bạn đang sử dụng các sự kiện trên bàn phím thì bạn sẽ không nhất thiết phải chỉnh sửa được, nhưng việc sử dụng con trỏ có thể lộn xộn tùy thuộc vào những gì bạn đang cố gắng thực hiện. Ngẫu nhiên, nó không chỉ là Chrome 17, nhưng khá nhiều tất cả các trình duyệt gần đây mà cư xử theo cách này - chắc chắn FF và Safari - trình duyệt IE quá Tôi tin rằng, mặc dù tôi đã không kiểm tra trong thời gian gần đây mà
Peter Bagnall
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.