JSFiddle - React, Tailwind, and code Playground
HTML
<div>
<div contenteditable="true" tabindex="0"></div>
<h1>Here is some stuff</h1>
<p>The <span contenteditable="true" tabindex="1">quick</span> brown fox <span contenteditable="true">jumped</span> over the lazy geese.</p>
<input/>
<button tabindex="3">Ok</button>
<button tabindex="1">Cancel</button>
<p tabindex="0">(This last content is tabbable.)</p>
</div>
JavaScript
function getTabStops(o, a, el) {
// Check if this element is a tab stop
if (el.tabIndex > 0) {
if (o[el.tabIndex]) {
o[el.tabIndex].push(el);
} else {
o[el.tabIndex] = [el];
}
} else if (el.tabIndex === 0) {
// Tab index "0" comes last so we accumulate it seperately
a.push(el);
}
// Check if children are tab stops
for (var i = 0, l = el.children.length; i < l; i++) {
getTabStops(o, a, el.children[i]);
}
}
function focusNext() {
var o = [],
a = [],
stops = [],
active = document.activeElement;
getTabStops(o, a, document.body);
// Use simple loops for maximum browser support
for (var i = 0, l = o.length; i < l; i++) {
if (o[i]) {
for (var j = 0, m = o[i].length; j < m; j++) {
stops.push(o[i][j]);
}
}
}
for (var i = 0, l = a.length; i < l; i++) {
stops.push(a[i]);
}
// If no items are focusable, then blur
if (stops.length === 0) {
active.blur();
return;
}
// Shortcut if current element is not focusable
if (active.tabIndex < 0) {
stops[0].focus();
return;
}
// Attempt to find the current element in the stops
for (var i = 0, l = stops.length; i < l; i++) {
if (stops[i] === active) {
if (i + 1 === stops.length) {
active.blur();
return;
}
stops[i+1].focus();
return;
}
}
// We shouldn't make it this far
active.blur();
}
document.addEventListener('keypress', function (e) {
if (e.which === 13) {
e.preventDefault();
focusNext();
}
});