Skip to content

Commit 0c955d1

Browse files
committed
feat(tpl): focus first or last item on ctrl+arrow keys
1 parent 98b30fc commit 0c955d1

File tree

2 files changed

+140
-101
lines changed

2 files changed

+140
-101
lines changed

src/tpl/asset/main.js

Lines changed: 84 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@
6464
}
6565
}
6666

67+
var selectorFirstAvailLi = 'li:not(.' + classNone + '):not(.' + classHeader + ')';
68+
69+
function getFirstFocusableSibling(container) {
70+
var li = container.querySelector(selectorFirstAvailLi);
71+
var a = li && li.querySelector('a');
72+
return a;
73+
}
74+
75+
function getLastFocusableSibling(container) {
76+
var a = container.querySelector('li a');
77+
a = getFocusableSibling(container, true, a);
78+
return a;
79+
}
80+
6781
function getMatchedFocusableSibling(container, isPrev, startA, buf, key) {
6882
var skipRound = buf === key;
6983
var matchKeyA;
@@ -150,77 +164,84 @@
150164
return getMatchedFocusableSibling(itemList, false, lookupStartA, lookupBuffer, key);
151165
}
152166

153-
document.addEventListener('keydown', function (e) {
154-
if (
155-
e.ctrlKey ||
156-
e.altKey ||
157-
SKIP_TAGS.indexOf(e.target.tagName) >= 0
158-
) {
167+
function getFocusItemByKeyPress(e) {
168+
if (SKIP_TAGS.indexOf(e.target.tagName) >= 0) {
159169
return;
160170
}
161171

162-
var newFocusEl;
163-
164172
if (e.key) {
165-
switch (e.key) {
166-
case LEFT:
167-
case ARROW_LEFT:
168-
if (!e.shiftKey && !e.metaKey) {
169-
newFocusEl = getFocusableSibling(pathList, true);
170-
}
171-
break;
172-
case RIGHT:
173-
case ARROW_RIGHT:
174-
if (!e.shiftKey && !e.metaKey) {
175-
newFocusEl = getFocusableSibling(pathList, false);
176-
}
177-
break;
178-
case UP:
179-
case ARROW_UP:
180-
if (!e.shiftKey && !e.metaKey) {
181-
newFocusEl = getFocusableSibling(itemList, true);
182-
}
183-
break;
184-
case DOWN:
185-
case ARROW_DOWN:
186-
if (!e.shiftKey && !e.metaKey) {
187-
newFocusEl = getFocusableSibling(itemList, false);
188-
}
189-
break;
190-
default:
191-
if (e.key.length === 1) {
192-
newFocusEl = lookup(e.key);
193-
}
194-
break;
173+
if (!e.altKey && !e.shiftKey) {
174+
switch (e.key) {
175+
case LEFT:
176+
case ARROW_LEFT:
177+
if (e.ctrlKey || e.metaKey) {
178+
return getFirstFocusableSibling(pathList);
179+
} else {
180+
return getFocusableSibling(pathList, true);
181+
}
182+
case RIGHT:
183+
case ARROW_RIGHT:
184+
if (e.ctrlKey || e.metaKey) {
185+
return getLastFocusableSibling(pathList);
186+
} else {
187+
return getFocusableSibling(pathList, false);
188+
}
189+
case UP:
190+
case ARROW_UP:
191+
if (e.ctrlKey || e.metaKey) {
192+
return getFirstFocusableSibling(itemList);
193+
} else {
194+
return getFocusableSibling(itemList, true);
195+
}
196+
case DOWN:
197+
case ARROW_DOWN:
198+
if (e.ctrlKey || e.metaKey) {
199+
return getLastFocusableSibling(itemList);
200+
} else {
201+
return getFocusableSibling(itemList, false);
202+
}
203+
}
204+
}
205+
if (!e.ctrlKey && !e.metaKey && e.key.length === 1) {
206+
return lookup(e.key);
195207
}
196208
} else if (e.keyCode) {
197-
switch (e.keyCode) {
198-
case ARROW_LEFT_CODE:
199-
if (!e.shiftKey && !e.metaKey) {
200-
newFocusEl = getFocusableSibling(pathList, true);
201-
}
202-
break;
203-
case ARROW_RIGHT_CODE:
204-
if (!e.shiftKey && !e.metaKey) {
205-
newFocusEl = getFocusableSibling(pathList, false);
206-
}
207-
break;
208-
case ARROW_UP_CODE:
209-
if (!e.shiftKey && !e.metaKey) {
210-
newFocusEl = getFocusableSibling(itemList, true);
211-
}
212-
break;
213-
case ARROW_DOWN_CODE:
214-
if (!e.shiftKey && !e.metaKey) {
215-
newFocusEl = getFocusableSibling(itemList, false);
216-
}
217-
break;
218-
default:
219-
if (e.keyCode >= 32 && e.keyCode <= 126) {
220-
newFocusEl = lookup(String.fromCharCode(e.keyCode));
221-
}
209+
if (!e.altKey && !e.shiftKey) {
210+
switch (e.keyCode) {
211+
case ARROW_LEFT_CODE:
212+
if (e.ctrlKey || e.metaKey) {
213+
return getFirstFocusableSibling(pathList);
214+
} else {
215+
return getFocusableSibling(pathList, true);
216+
}
217+
case ARROW_RIGHT_CODE:
218+
if (e.ctrlKey || e.metaKey) {
219+
return getLastFocusableSibling(pathList);
220+
} else {
221+
return getFocusableSibling(pathList, false);
222+
}
223+
case ARROW_UP_CODE:
224+
if (e.ctrlKey || e.metaKey) {
225+
return getFirstFocusableSibling(itemList);
226+
} else {
227+
return getFocusableSibling(itemList, true);
228+
}
229+
case ARROW_DOWN_CODE:
230+
if (e.ctrlKey || e.metaKey) {
231+
return getLastFocusableSibling(itemList);
232+
} else {
233+
return getFocusableSibling(itemList, false);
234+
}
235+
}
236+
}
237+
if (!e.ctrlKey && !e.metaKey && e.keyCode >= 32 && e.keyCode <= 126) {
238+
return lookup(String.fromCharCode(e.keyCode));
222239
}
223240
}
241+
}
242+
243+
document.addEventListener('keydown', function (e) {
244+
var newFocusEl = getFocusItemByKeyPress(e);
224245
if (newFocusEl) {
225246
e.preventDefault();
226247
newFocusEl.focus();

src/tpl/asset/main.js.go

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ var siblingA = siblingLI.querySelector('a');
6161
return siblingA;
6262
}
6363
}
64+
var selectorFirstAvailLi = 'li:not(.' + classNone + '):not(.' + classHeader + ')';
65+
function getFirstFocusableSibling(container) {
66+
var li = container.querySelector(selectorFirstAvailLi);
67+
var a = li && li.querySelector('a');
68+
return a;
69+
}
70+
function getLastFocusableSibling(container) {
71+
var a = container.querySelector('li a');
72+
a = getFocusableSibling(container, true, a);
73+
return a;
74+
}
6475
function getMatchedFocusableSibling(container, isPrev, startA, buf, key) {
6576
var skipRound = buf === key;
6677
var matchKeyA;
@@ -136,75 +147,82 @@ lookupBuffer += key;
136147
delayClearLookupContext();
137148
return getMatchedFocusableSibling(itemList, false, lookupStartA, lookupBuffer, key);
138149
}
139-
document.addEventListener('keydown', function (e) {
140-
if (
141-
e.ctrlKey ||
142-
e.altKey ||
143-
SKIP_TAGS.indexOf(e.target.tagName) >= 0
144-
) {
150+
function getFocusItemByKeyPress(e) {
151+
if (SKIP_TAGS.indexOf(e.target.tagName) >= 0) {
145152
return;
146153
}
147-
var newFocusEl;
148154
if (e.key) {
155+
if (!e.altKey && !e.shiftKey) {
149156
switch (e.key) {
150157
case LEFT:
151158
case ARROW_LEFT:
152-
if (!e.shiftKey && !e.metaKey) {
153-
newFocusEl = getFocusableSibling(pathList, true);
159+
if (e.ctrlKey || e.metaKey) {
160+
return getFirstFocusableSibling(pathList);
161+
} else {
162+
return getFocusableSibling(pathList, true);
154163
}
155-
break;
156164
case RIGHT:
157165
case ARROW_RIGHT:
158-
if (!e.shiftKey && !e.metaKey) {
159-
newFocusEl = getFocusableSibling(pathList, false);
166+
if (e.ctrlKey || e.metaKey) {
167+
return getLastFocusableSibling(pathList);
168+
} else {
169+
return getFocusableSibling(pathList, false);
160170
}
161-
break;
162171
case UP:
163172
case ARROW_UP:
164-
if (!e.shiftKey && !e.metaKey) {
165-
newFocusEl = getFocusableSibling(itemList, true);
173+
if (e.ctrlKey || e.metaKey) {
174+
return getFirstFocusableSibling(itemList);
175+
} else {
176+
return getFocusableSibling(itemList, true);
166177
}
167-
break;
168178
case DOWN:
169179
case ARROW_DOWN:
170-
if (!e.shiftKey && !e.metaKey) {
171-
newFocusEl = getFocusableSibling(itemList, false);
180+
if (e.ctrlKey || e.metaKey) {
181+
return getLastFocusableSibling(itemList);
182+
} else {
183+
return getFocusableSibling(itemList, false);
172184
}
173-
break;
174-
default:
175-
if (e.key.length === 1) {
176-
newFocusEl = lookup(e.key);
177185
}
178-
break;
186+
}
187+
if (!e.ctrlKey && !e.metaKey && e.key.length === 1) {
188+
return lookup(e.key);
179189
}
180190
} else if (e.keyCode) {
191+
if (!e.altKey && !e.shiftKey) {
181192
switch (e.keyCode) {
182193
case ARROW_LEFT_CODE:
183-
if (!e.shiftKey && !e.metaKey) {
184-
newFocusEl = getFocusableSibling(pathList, true);
194+
if (e.ctrlKey || e.metaKey) {
195+
return getFirstFocusableSibling(pathList);
196+
} else {
197+
return getFocusableSibling(pathList, true);
185198
}
186-
break;
187199
case ARROW_RIGHT_CODE:
188-
if (!e.shiftKey && !e.metaKey) {
189-
newFocusEl = getFocusableSibling(pathList, false);
200+
if (e.ctrlKey || e.metaKey) {
201+
return getLastFocusableSibling(pathList);
202+
} else {
203+
return getFocusableSibling(pathList, false);
190204
}
191-
break;
192205
case ARROW_UP_CODE:
193-
if (!e.shiftKey && !e.metaKey) {
194-
newFocusEl = getFocusableSibling(itemList, true);
206+
if (e.ctrlKey || e.metaKey) {
207+
return getFirstFocusableSibling(itemList);
208+
} else {
209+
return getFocusableSibling(itemList, true);
195210
}
196-
break;
197211
case ARROW_DOWN_CODE:
198-
if (!e.shiftKey && !e.metaKey) {
199-
newFocusEl = getFocusableSibling(itemList, false);
212+
if (e.ctrlKey || e.metaKey) {
213+
return getLastFocusableSibling(itemList);
214+
} else {
215+
return getFocusableSibling(itemList, false);
200216
}
201-
break;
202-
default:
203-
if (e.keyCode >= 32 && e.keyCode <= 126) {
204-
newFocusEl = lookup(String.fromCharCode(e.keyCode));
205217
}
206218
}
219+
if (!e.ctrlKey && !e.metaKey && e.keyCode >= 32 && e.keyCode <= 126) {
220+
return lookup(String.fromCharCode(e.keyCode));
207221
}
222+
}
223+
}
224+
document.addEventListener('keydown', function (e) {
225+
var newFocusEl = getFocusItemByKeyPress(e);
208226
if (newFocusEl) {
209227
e.preventDefault();
210228
newFocusEl.focus();

0 commit comments

Comments
 (0)