Vue
by khamer
HTML
<div id="app">
<button>before</button>
<nav>
<a href="#link1" v-kbindex:a="">Link 1</a>
<a href="#link2" v-kbindex:a="">Link 2</a>
<a href="#link3" v-kbindex:a="">Link 3</a>
<a href="#link4" v-kbindex:a="">Link 4</a>
</nav>
<button>after</button>
<nav>
<a href="#link1" v-kbindex:b="">Link 1</a>
<a href="#link2" v-kbindex:b="">Link 2</a>
<a href="#link3" v-kbindex:b="">Link 3</a>
<a href="#link4" v-kbindex:b="">Link 4</a>
</nav>
<button>blah</button>
</div>
SCSS
html {
background-color: #111;
}
body {
background-color: #fff;
margin: 3vmin;
padding: 3vmin;
}
Vue
Vue.directive('kbindex', (() => {
let indices = {}
const createIndex = (index, el) => {
indices[index] = {
elements: [ el ],
add(el) {
this.elements.push(el)
el.setAttribute('tabindex', -1)
},
focus({ target }) {
this.elements.forEach(el => {
if (el === target) {
el.setAttribute('tabindex', 0)
} else {
el.setAttribute('tabindex', -1)
}
})
},
handler({ key, target }) {
const l = this.elements.length;
let i = this.elements.indexOf(target);
if (key == 'ArrowLeft') {
i -= 1
} else if (key == 'ArrowRight') {
i += 1
} else {
return
}
let el = this.elements[(i + l) % l]
el.setAttribute('tabindex', 0)
target.setAttribute('tabindex', -1)
el.focus()
}
}
}
return {
bind(el, { arg: index }) {
if (index in indices) {
indices[index].add(el)
} else {
createIndex(index, el)
}
console.log(index)
el.addEventListener('keyup', evt => indices[index].handler(evt))
el.addEventListener('focus', evt => indices[index].focus(evt))
}
}
})())
new Vue({
el: "#app",
})