-
Notifications
You must be signed in to change notification settings - Fork 0
/
roving_tabindex.js
112 lines (93 loc) · 2.85 KB
/
roving_tabindex.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
'use strict';
class rovingTabindex {
constructor(groupNode) {
this.items = Array.from(groupNode);
this.firstItem = null;
this.lastItem = null;
this.previouslyFocused = null;
for (var i = 0; i < this.items.length; i += 1) {
var item = this.items[i];
item.tabIndex = -1;
item.setAttribute('data-selected', 'false');
item.addEventListener('keydown', this.onKeydown.bind(this));
if (!this.firstItem) {
this.firstItem = item;
}
this.lastItem = item;
}
this.setSelectedItem(this.firstItem);
}
setSelectedItem(currentItem) {
for (var i = 0; i < this.items.length; i += 1) {
var item = this.items[i];
if (currentItem === item) {
item.setAttribute('data-selected', 'true');
item.setAttribute ('tabindex', '0');
} else {
item.setAttribute('data-selected', 'false');
item.setAttribute ('tabindex', '-1');
}
}
}
moveFocusToItem(currentItem) {
currentItem.focus();
}
moveFocusToPreviousItem(currentItem) {
var index;
if (currentItem === this.firstItem) {
this.moveFocusToItem(this.lastItem);
this.setSelectedItem(this.lastItem);
} else {
index = this.items.indexOf(currentItem);
this.moveFocusToItem(this.items[index - 1]);
this.setSelectedItem(this.items[index - 1]);
}
}
moveFocusToNextItem(currentItem) {
var index;
if (currentItem === this.lastItem) {
this.moveFocusToItem(this.firstItem);
this.setSelectedItem(this.firstItem);
} else {
index = this.items.indexOf(currentItem);
this.moveFocusToItem(this.items[index + 1]);
this.setSelectedItem(this.items[index + 1]);
}
}
/* EVENT HANDLERS */
onKeydown(event) {
this.previouslyFocused = event.currentTarget;
switch (event.code) {
case 'ArrowLeft':
this.moveFocusToPreviousItem(this.previouslyFocused);
break;
case 'ArrowRight':
this.moveFocusToNextItem(this.previouslyFocused);
break;
case 'ArrowUp':
this.moveFocusToPreviousItem(this.previouslyFocused);
break;
case 'ArrowDown':
this.moveFocusToNextItem(this.previouslyFocused);
break;
// when user moves tabs from the group
case 'Tab':
this.setSelectedItem(this.previouslyFocused);
break;
// when user moves shift+tabs from the group
case 'ShiftLeft':
this.setSelectedItem(this.previouslyFocused);
break;
default:
break;
}
}
}
// Initialize list of elements included in roving tabindex
window.addEventListener('load', function () {
// Select the group of elements to include in the roving tabindex
var itemlists = document.querySelectorAll('[class="book-card__link"]');
for (var i = 0; i < itemlists.length; i++) {
new rovingTabindex(itemlists);
}
});