Jak mogę nadać fokus klawiatury do DIV i dołączyć do niego programy obsługi zdarzeń klawiatury?


84

Buduję aplikację, w której chcę mieć możliwość kliknięcia prostokąta reprezentowanego przez DIV, a następnie użyj klawiatury, aby przenieść ten DIV, wyświetlając zdarzenia klawiatury.

Zamiast używać detektora zdarzeń dla tych zdarzeń klawiatury na poziomie dokumentu, czy mogę nasłuchiwać zdarzeń klawiatury na poziomie DIV, być może poprzez ustawienie fokusu na klawiaturze?

Oto uproszczony przykład ilustrujący problem:

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

Po kliknięciu wewnętrznego DIV staram się nadać mu fokus, ale kolejne zdarzenia klawiatury są zawsze odbierane na poziomie dokumentu, a nie na moim odbiorniku zdarzeń na poziomie DIV.

Czy muszę po prostu zaimplementować specyficzne dla aplikacji pojęcie fokusu na klawiaturze?

Powinienem dodać, że potrzebuję tego tylko do pracy w Firefoksie.



1
Niezupełnie oszustwo - zapytał jakieś dwa lata wcześniej, a to pytanie, jak odbierać zdarzenia klawiatury na dowolnych elementach, zamiast używać focus()funkcji.
Paul Dixon,

Odpowiedzi:


166

Sorted - dodałem atrybut tabindex do docelowego DIV, co powoduje, że np. Odbiera zdarzenia z klawiatury

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

Informacje zebrane z http://www.w3.org/WAI/GL/WCAG20/WD-WCAG20-TECHS/SCR29.html


7
Ponadto, jeśli nie chcesz, aby element DIV miał przerywaną niebieską ramkę, gdy jest skupiony, możesz go nadać stylowi outline: 0px solid tranparent;. Zobacz: stackoverflow.com/a/2260788/402807
AlcubierreDrive

4
Lub ustaw tabindex="-1", to również zapobiegnie uzyskaniu przerywanej ramki.
troglobit

Nie mogę tego w ogóle uruchomić w Chrome 60 i FF 54. A IE11 magicznie robi to, co trzeba, nawet bez tabindex. Czy ta odpowiedź jest nieaktualna?
jlh

To nie działa dla mnie w obecnej przeglądarce Firefox. Przeglądarka obsługuje wprowadzanie z klawiatury. To samo dotyczy skrzypiec.
Kwebble

1
pozbycie się outlinenie jest dostępne. jeśli nie podoba ci się wygląd, polecam dać inne wizualne wskazanie, że element jest skupiony, zanim pozbędziesz sięoutline
sleeparrow

5

Odpowiedź Paula działa dobrze, ale możesz również użyć contentEditable, w ten sposób ...

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

W niektórych przypadkach może być lepsze.


6
Jeśli to zrobisz, Chrome 17 umieszcza kursor na elemencie na fokusie i możesz wpisywać rzeczy na elemencie. Nie polecałbym tego.
Seppo Erviälä

1
@Seppo, to dobra uwaga. Jeśli konsumujesz zdarzenia klawiatury, niekoniecznie będziesz w stanie edytować, ale posiadanie kursora może być bałagan w zależności od tego, co próbujesz zrobić. Nawiasem mówiąc, to nie tylko Chrome 17, ale prawie wszystkie najnowsze przeglądarki zachowują się w ten sposób - na pewno FF i Safari - IE też uważam, chociaż ostatnio tego nie testowałem
Peter Bagnall
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.