#javascript #html
#javascript #HTML
Вопрос:
У меня есть заголовок и переключаемое меню, в котором я хочу, чтобы фокус переходил с кнопки меню на первую ссылку в меню при нажатии кнопки. Из-за дизайна / структуры кнопка меню и меню не могут находиться рядом друг с другом. Меню состоит из списка с названием ссылки и кнопки. Но у меня возникли некоторые проблемы, чтобы заставить его работать. По сути, я хочу естественного способа перехода к меню с помощью клавиши tab, даже если кнопка и меню не могут быть рядом друг с другом.
Это мой js:
const button = document.querySelector(".button");
const list = document.querySelector(".list");
button.addEventListener("click", this.setFocus.bind(this));
function setFocus(e) {
if(list.classList.contains("show")) {
if (e.keyCode == 9) {
list.querySelector("a").focus();
}
}
}
И скрипка
Комментарии:
1. Каким образом вопрос неясен?
2. Для меня желаемый результат не ясен. Не могли бы вы описать это лучше?
3. Что вы имеете в виду под «фокусом»? Вы хотите нажать «Меню» и перейти к первой ссылке через ее привязку?
4. Если я нажму «Меню», меню переключится (откроется), тогда я хочу, чтобы фокус был сосредоточен на первой ссылке в меню, когда я нажимаю клавишу tab.
5. Почему вы проверяете
keyCode
событие щелчка?
Ответ №1:
Если вы удалите if (e.keyCode == 9)
проверку, ваш код будет работать так, как ожидалось.
По умолчанию в большинстве браузеров focus
эффект не будет отображать визуальный эффект для всех элементов, если он не применяется с клавиатуры, поэтому в этом примере я добавил красный фон, чтобы подчеркнуть, что происходит.
const button = document.querySelector(".button");
const list = document.querySelector(".list");
button.addEventListener("click", this.setFocus.bind(this));
function setFocus(e) {
if (list.classList.contains("show")) {
list.querySelector("a").focus();
}
}
:focus {
background: red;
}
<button class="button">Menu</button>
<a href="#">Another link</a>
<ul class="list show">
<li class="li">
<a class="link" href="#">Link</a>
<button class="button">chevron</button>
</li>
<li class="li">
<a class="link" href="#">Link</a>
<button class="button">chevron</button>
</li>
<li class="li">
<a class="link" href="#">Link</a>
<button class="button">chevron</button>
</li>
</ul>
Если вам нужен визуальный эффект в этом случае, вы можете применить стиль к .link:focus
(Chrome использует что-то вроде outline: #000 1px;
)
Комментарии:
1. Хорошо, я понимаю это, спасибо! Но то, что я пытался выполнить с помощью проверки ключа, заключалось в том, что я хочу, чтобы фокус находился в меню после нажатия вкладки. Когда вы перемещаетесь только с помощью клавиатуры, затем вы переходите к кнопке меню, открываете меню, а затем переходите к первому элементу меню.
2. @pistevw Если вы нажмете enter на кнопке, она все равно должна поменять фокус для вас. Вы имеете в виду, что хотите открыть подменю, когда первая кнопка получит фокус? Если это так, вы также можете прослушать событие фокусировки:
button.addEventListener("focus", this.setFocus.bind(this));
3. Я хочу иметь возможность переходить от кнопки меню к меню с помощью клавиатуры. Итак, когда я открываю меню, например, с помощью клавиши пробела, и после этого нажимаю клавишу tab ‘, я хочу, чтобы фокус переместился на первую ссылку меню. Извините, если я объясняю сложным способом.
4. Хм, ну, то, что уже есть в ответе, должно это сделать. Одна вещь, которая может быть проблемой, это если у вас есть код, который применяет
.show
класс, который вы не включили в вопрос. ЕслиsetFocus()
применяется runs beforeshow
, он не будет работать.5. Я обновил скрипку, чтобы меню отображалось при нажатии кнопки, но прямо сейчас фокус переходит прямо на ссылку меню, когда я открываю меню. Я хочу, чтобы фокус переместился на ссылку меню после открытия меню. Итак: откройте меню, затем перейдите по ссылке на меню.
Ответ №2:
Я думаю, вы пытаетесь переходить по ссылкам, не фокусируясь на кнопках? В этом случае вы можете установить tabindex
для кнопок значение -1. Это предотвращает попадание их в фокус при переходе по элементам.
<button class="button" tabindex="-1">chevron</button>
Кроме того, вы смешиваете свои события. Событие «щелчок», и вы проверяете нажатие вкладки. Просто избавьтесь от этой проверки, чтобы автоматически сфокусироваться на первом элементе.
function setFocus(e) {
if(list.classList.contains("show")) {
list.querySelector("a").focus();
}
}
Комментарии:
1. Шевроны — это кнопки, которые открывают подменю, поэтому их нужно фокусировать. Если я уберу проверку нажатия клавиш, когда я нажимаю кнопку меню, фокусируется первый шеврон, а не первая ссылка. Почему это так?
2. Это потому, что код устанавливает фокус на первую ссылку в списке. Нажатие tab затем перемещает фокус на следующий элемент, который является кнопкой chevron. Добавление проверки нажатия клавиш нарушает логику, поэтому функция не работает и никогда не устанавливает фокус. Фокус остается на кнопке меню, и нажатие tab переходит к следующему элементу, который является привязкой «другая ссылка». Это точно так же, как полное удаление обработчика кликов.
3. Я вроде это понимаю. Но как я могу сфокусироваться на ссылке, а не на шевроне, я пытаюсь выполнить обратную фокусировку, когда нажимаю shift tab, а затем возвращаю фокус на кнопку меню. Если я напишу
anotherLink.focus();
, кнопка меню получит фокус, но не если я напишуmenuButton.focus();
, возможно ли, что вы могли бы объяснить, как я могу добиться этого правильно?4. На самом деле он уже сфокусирован на ссылке. Попробуйте использовать внешние ссылки, а не
#
для того, чтобы было понятнее, что происходит. Нажмите кнопку меню, затем нажмите enter. Вы перейдете к URL-адресу первой ссылки. Я обновил скрипку: jsfiddle.net/npx4rLqj5. Я думаю, что ваша проблема связана с вашими стилями, поэтому вы не можете видеть, что сфокусировано, а что нет. Вместо этого взгляните на эту скрипку, добавив какой-то уродливый CSS, чтобы выделить сфокусированную ссылку. jsfiddle.net/npx4rLqj/1