Як я можу зосередити клавіатуру на DIV і приєднати до нього обробники подій клавіатури?


83

Я будую додаток, де хочу мати можливість клацнути прямокутник, представлений DIV, а потім за допомогою клавіатури переміщувати цей DIV, перелічуючи події клавіатури.

Замість того, щоб використовувати прослуховувач подій для тих подій клавіатури на рівні документа, чи можу я прослуховувати події клавіатури на рівні DIV, можливо, надаючи йому фокус на клавіатурі?

Ось спрощений зразок для ілюстрації проблеми:

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

При натисканні на внутрішній DIV я намагаюся сфокусувати його, але подальші події клавіатури завжди підбираються на рівні документа, а не на моєму прослуховувачі подій DIV.

Мені просто потрібно реалізувати специфічне для програми поняття фокусу на клавіатурі?

Слід додати, що мені це потрібно лише для роботи у Firefox.



1
Насправді не дурень - він запитував за два роки до цього, і це питання про те, як отримувати події клавіатури на довільних елементах, а не за допомогою focus()функції.
Пол Діксон,

Відповіді:


165

Відсортовано - я додав атрибут tabindex до цільового DIV, що змушує його підбирати події клавіатури, наприклад

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

Інформація отримана з http://www.w3.org/WAI/GL/WCAG20/WD-WCAG20-TECHS/SCR29.html


6
Крім того, якщо ви не хочете, щоб div отримав пунктирну синю рамку, коли вона сфокусована, ви можете її стилізувати outline: 0px solid tranparent;. Див .: stackoverflow.com/a/2260788/402807
AlcubierreDrive

4
Або встановлений tabindex="-1", що також заважатиме йому отримувати пунктирну межу.
троглобіт

Я взагалі не можу змусити це працювати в Chrome 60 і FF 54. А IE11 магічно робить правильно, навіть без tabindex. Ця відповідь застаріла?
jlh

Це не працює для мене в поточному Firefox. Браузер обробляє введення з клавіатури. Те саме щодо скрипки.
Квебл

1
позбутися від цього outlineнедоступно. якщо вам не подобається, як це виглядає, я рекомендую дати якийсь інший візуальний вказівник на те, що елемент сфокусований, перш ніж позбутися відoutline
сонник

5

Відповідь Павла чудово працює, але ви також можете використовувати contentEditable, наприклад ...

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

У деяких випадках може бути кращим.


6
Якщо ви зробите це, Chrome 17 наводить курсор на елемент на фокус, і ви можете вводити елементи на ньому. Я б не рекомендував цього.
Seppo Erviälä

1
@Seppo, це хороший момент. Якщо ви споживаєте події на клавіатурі, то вам не обов'язково вдасться їх редагувати, але наявність курсору може бути брудним, залежно від того, що ви намагаєтесь зробити. До речі, так поводяться не лише Chrome 17, але майже всі останні браузери - безумовно, FF та Safari - IE, я також вважаю, хоча останнім часом не тестував
Peter Bagnall
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.