2012-05-05 27 views
5

Tình hình: Tôi có một handler keydown với một switch cho khóa những gì được nhấn, công cụ khá chuẩn, nhưng khi một phím bất kỳ được tổ chức xuống keydown cháy sự kiện lặp đi lặp lại (chứ không phải chỉ một lần khi phím được nhấn thực sự).Force KeyDown để bắn chỉ một lần mỗi keyCode

Tại sao đó là một vấn đề: Tôi muốn giữ keydown lắng nghe tích cực, tức là khả năng phát hiện nhiều hơn một chìa khóa được ép cùng một lúc, nhưng chỉ có ngọn lửa sự kiện một lần mỗi keydown. Tôi sẽ muốn làm một cái gì đó trên keyup cho rằng keyCode dựa trên thời gian từ lên xuống, nhưng thời gian đó là nhận được hơi say lên vì nhiều firings.

Những gì tôi đã cố gắng: Tôi hiện đang giữ một danh sách các keyCodes mà xuống, và kiểm tra đối với những người trong keydown xử lý của tôi để giữ cho các hành vi mặc định xảy ra nếu keyCode có trong danh sách của tôi. Tuy nhiên, sự kiện này vẫn diễn ra rất thường xuyên và tôi lo ngại về hiệu quả/sự thanh lịch của giải pháp này.

Câu hỏi thực tế: Có cách nào tốt để hạn chế bắn của sự kiện keydown để chỉ khi phím được thể chất bị đẩy xuống, hoặc chỉ để nghe cho mã phím cụ thể?

+0

"tức là có thể phát hiện nhiều hơn một phím được nhấn cùng một lúc" Điều đó có nghĩa là gì? – epascarello

+0

Ví dụ: giữ phím 'y', sau đó nhấn và giữ phím 'o'. Điều này loại trừ giải pháp xóa sự kiện keydown và thêm lại sau khi khóa. –

Trả lời

8

Trong trình xử lý khóa, kiểm tra xem khóa có giống với khóa được xử lý cuối cùng hay không. Nếu có, hãy thoát sớm. Khi khóa, hãy quên phím cuối cùng được xử lý.

Ví dụ:

var lastEvent; 
var heldKeys = {}; 

window.onkeydown = function(event) { 
    if (lastEvent && lastEvent.keyCode == event.keyCode) { 
     return; 
    } 
    lastEvent = event; 
    heldKeys[event.keyCode] = true; 
}; 

window.onkeyup = function(event) { 
    lastEvent = null; 
    delete heldKeys[event.keyCode]; 
};​ 

Demo here (bấm vào "Kết quả" bảng điều khiển và nhấn phím).

0

Xác định boolean để ghi nếu phím được nhấn. Đặt nó thành true trong sự kiện quan trọng. Kiểm tra vòng lặp chính của bạn nếu giá trị là đúng và xử lý sự kiện, và đặt phím được nhấn thành false. Có một boolean khác để ghi lại nếu khóa được giải phóng (ban đầu là false). Nếu sự kiện khóa khởi động, hãy đặt sự kiện đó thành bản phát hành. Chỉ đặt giá trị được nhấn phím thành true (trong sự kiện từ khóa) nếu giá trị "được giải phóng" cũng đúng.

+0

Đây là một câu trả lời khá hay. Điều duy nhất tôi có thể thêm là tôi sẽ xác định một mảng các đối tượng để lưu trữ các boolean trong cho mỗi mã khóa trong khi nó được nhấn, và trong đối tượng đó sẽ là [{"43": true}, ...] và sau đó chỉ cần xóa mã khóa đó như đã đề xuất ở trên. – LocalPCGuy

+0

Đây thực sự là những gì tôi đang làm bây giờ, xin lỗi nếu nó không rõ ràng. Tôi đang giữ các mã khóa 'xuống' được lưu trữ và xóa chúng trên khóa. Tôi quan tâm đến bất kỳ lựa chọn thay thế nào có thể hiệu quả hơn kiểm tra nhiều lần trong một giây so với danh sách các mã phím của tôi. –

0

Dưới đây là một ví dụ về những gì tôi nghĩ rằng bạn muốn đạt được: jsFiddle Example

Hiện nay các kết hợp tổ hợp phím CTRL + B là người duy nhất Thats phát hiện. Chỉ cần nhấn một số để có được nhật ký hoạt động. Khi khóa đã được nhấn xuống, nó sẽ phát hiện hành động giữ.

Các vấn đề liên quan