tabindex native javascript
Ребята, подскажите, пожалуйста, как мне решить следующую задачу:
У меня есть некий список элементов:
ul.nav__list
li.nav__item
a.nav__item-link
span Players
li.nav__item
a.nav__item-link
span Coaches
li.nav__item
a.nav__item-link
span Refereed
div.navigation
a(href="#") Navigation
Мне необходимо реализовать следующий функционал. После загрузки документа, при нажатии на клавишу Tab, ссылки поочередно получают focus. Мне необходимо, чтобы порядок был слудующий. После фокуса на первой ссылке: a.nav__item-link при следующем нажатии на кноку Tab, у меня фокус перешел на: a(href="#") Navigation Затем на вторую ссылку: a.nav__item-link А после этого сноав на: a(href="#") Navigation Далее на третью ссылку a.nav__item-link И при следующем нажатии на Tab снова на: a(href="#") Navigation И так далее. И наиболее важный вопрос: как мне в момент фокуса ссылки, вызывать какой либо обработчик. Пример логики, которую я хочу реализовать есть на следующем сайте: http://www.kentfa.com/ |
<style>
ul li { display:inline;
border: 1px solid gray;
}
div a{ border: 1px solid gray; }
</style>
<ul class='nav__list'>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Players </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Coaches </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Referees </span>
</a>
</li>
<div class='navigation'>
<a href="#"><span> Navigation</span> </a>
</div>
<script>
var flag = true, idx = 0;
var list = document.querySelectorAll('li a');
var nav = document.querySelector('div a');
nav.focus();
document.onkeydown = function(e) {
if(e.keyCode == 9) {
e.preventDefault();
if(flag) {
list[idx].focus();
// здесь можно вызвать обработчик
idx = (idx < list.length - 1)? idx + 1: 0;
}
else { nav.focus(); }
flag = !flag;
}
}
document.onkeyup = function(e) { if(e.keyCode == 9) e.preventDefault(); }
</script>
|
Спасибо. Но в данном случае мне не надо делать e.preventDefault();
А без этого функция работает не корректно. |
s24344,
Делайте e.preventDefault(); только для e.keyCode == 9 Внес изменения в пример пост 2 И обработчики можно вешать не на document.onkeydown, а на нужный вам блок, в котором лежат эти элементы - если надо, чтобы в других частях страницы TAB работал по-другому |
Спасибо.
|
Вы могли бы подсказать ответ ещё на один вопрос. А если использовать событие focus, а не привязываться к onkeydown. Каким образом мне сделать такую же очередность? Например с помощью атрибута tabindex.
|
Цитата:
Цитата:
|
Я уже реализовал задачу с помощью вашего решения, и всё работало отлично. Но teamlead сказал, что это не вариант и надо сделать с помощью tabindex. Сейчас это реализовываю, onFocusPrimaryLink(event) { console.log(event.target); } при событии focus и динамически меняю tabindex.
|
По фокусу c tabindex.
<style>
ul li { display:inline;
border: 1px solid gray;
}
div a{ border: 1px solid gray; }
:focus { background-color:lightgreen;}
</style>
<ul class='nav__list'>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="2">
<span> Players </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="4">
<span> Coaches </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="6">
<span> Referees </span>
</a>
</li>
</ul>
<div class='navigation'>
<a href="#" tabindex="1"><span> Navigation</span> </a>
</div>
<script>
var refs = document.querySelectorAll('a');
var list = document.querySelectorAll('li a');
var nav = document.querySelector('div a');
nav.focus();
[].forEach.call(refs, function(it) {
it.addEventListener('focus', function() {
var ti = +this.getAttribute('tabindex');
if(this == nav && (ti - 1)%list.length == 0) {
[].forEach.call(list, function(el) {
el.setAttribute('tabindex',(+el.getAttribute('tabindex') + list.length * 2).toString() );
});
}
ti = (ti + 1).toString();
if(this != nav) nav.setAttribute('tabindex',ti );
});
});
</script>
|
tab and focus
Цитата:
ниже иная вариация того, что предложил Dilettante_Pro,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
</head>
<body>
<style>
ul li { display:inline;
border: 1px solid gray;
}
div a{ border: 1px solid gray; }
:focus {
background-color: #228B22;
}
</style>
<ul class='nav__list'>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Players </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Coaches </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link'>
<span> Referees </span>
</a>
</li>
</ul>
<div class='navigation' >
<a href="#"><span> Navigation</span> </a>
</div>
<script src="https://cdn.polyfill.io/v1/polyfill.js?Element.prototype.closest"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var tabindex = document.querySelectorAll("[tabindex]");
var li = document.querySelectorAll(".nav__item");
var nav = document.querySelector(".navigation");
var idx = 0;
var ln = li.length;
[].forEach.call(tabindex, function(elem) {
elem.removeAttribute("tabindex")
});
[].forEach.call(li, function(elem, i) {
elem.setAttribute("tabindex", i);
elem.addEventListener("click", function() {
idx = i
})
});
li[0].focus();
nav.setAttribute("tabindex", ln);
document.addEventListener("keydown",
function(event) {
if (event.keyCode == 9 && event.target.closest(".nav__item")) {
event.preventDefault();
nav.focus()
} else if (event.keyCode == 9 && event.target.closest(".navigation")) {
event.preventDefault();
idx = ++idx % ln;
li[idx].focus()
}
}, true)
});
</script>
</body>
</html>
|
рони,
Цитата:
|
Dilettante_Pro,
ок, но я предполагал только некую секретную установку tabindex, без следующего изменения. :) |
Цитата:
Если не менять tabindex у li a, то нужен в конце холостой элемент, на котором делать focus() на начало. |
Вариант, работающий также в IE и FF
<style>
ul li { display:inline;
border: 1px solid gray;
}
div a{ border: 1px solid gray; }
:focus { background-color:lightgreen;}
</style>
<ul class='nav__list'>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="2">
<span> Players </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="4">
<span> Coaches </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="6">
<span> Referees </span>
</a>
</li>
<li class = 'nav__item'>
<a href="#" class='nav__item-link' tabindex="8">
<span> ⇐ </span>
</a>
</li>
</ul>
<div class='navigation'>
<a href="#" tabindex="1"><span> Navigation</span> </a>
</div>
<script>
var refs = document.querySelectorAll('a');
var list = document.querySelectorAll('li a');
var nav = document.querySelector('div a');
nav.focus();
[].forEach.call(refs, function(it) {
it.addEventListener('focus', function() {
var ti = +this.getAttribute('tabindex');
ti = (ti + 1).toString();
if(this != nav) nav.setAttribute('tabindex',ti );
if(this == list[list.length - 1]) list[0].focus();
});
});
</script>
|
Замучился с корректным решением, поэтому более детально опишу задачу, очень надеюсь на вашу помощь.
#app
a.some-links link
a.some-links link
ul.list
li.list__item
a(href="#" data-nav-id="_1").list__link First
li.list__item
a(href="#" data-nav-id="_2").list__link Second
li.list__item
a(href="#" data-nav-id="_3").list__link Third
ul.nav
li(data-nav-id="_1").nav__item
a(href="#").nav__link first
.nav__popup
ul.nav__popup-list
li.nav__popup-item
a(href="#").nav__popup-link first 1
li.nav__popup-item
a(href="#").nav__popup-link first 2
li(data-nav-id="_2").nav__item
a(href="#").nav__link second
.nav__popup
ul.nav__popup-list
li.nav__popup-item
a(href="#").nav__popup-link second 1
li(data-nav-id="_3").nav__item
a(href="#").nav__link Third
.nav__popup
ul.nav__popup-list
li.nav__popup-item
a(href="#").nav__popup-link third 1
a(href="#").nav-pane pane
a.some-links link
a.some-links link
Должно работать как данном примере: http://www.kentfa.com/ При первом нажатии на tab, первый элемент a или button принимает focus, после чего в default порядке происходит смена focus, но когда focus принимает .list__link, далее при нажатии на клавишу tab, focus переходит на .nav-pane(без фокуса он скрыт). Далее мы нажимаем на enter (space), фактически это событие click, и появляется .nav__item (с соответствуещей привязкой по data атрибутам), далее мы при нажатии на tab также меняем фокус по default порядку. Когда же будет последний элемент .list__item, мы в последний раз перейдем на .nav__popup, и далее вниз по a (button). И также важно, что default навигация, смена focus, при shift + tab, также корректно работает. |
Цитата:
|
Если сказать проще.
http://www.kentfa.com/ В этом примере при загрузке страницы мы tab доходим до меню. Далее после каждого пункта переход на панель открытия. Можно сказать не стандартный tabindex. |
Цитата:
|
Всё, разобрался, спасибо.
|
| Часовой пояс GMT +3, время: 20:54. |