Reputation: 4533
I am trying to navigate through the div elements using arrow keys. I know how to achieve it in JavaScript however I am struggling doing it "vue way". i know there should not be any differences but it simply does not work.
I have made sandbox for you to check what is going on. It is working if I am not using Vue
In Vue I get the following error because of this line:
Cannot read property 'focus' of null
document.activeElement.parentNode.previousSibling.firstChild.focus();
Can anybody tell me what I am doing wrong? Is the v-for
the error source or are there some other problems?
Upvotes: 2
Views: 9945
Reputation: 20329
Why not take a data-driven approach to this?
You have an array of items. You can set an active property on each item and toggle that to true
or false
.
Your up and down keys will change the array pointer and set the current pointer item to true. This way you do not have to do any DOM selection.
Upvotes: 1
Reputation: 12669
It really depends on why you need a focus
. If it's just to highlight something, you can use a secondary variable to track which one you're currently highlighting and add a class to it instead
https://codesandbox.io/s/300vxzkyk5
<template>
<div>
<input ref="input" type="text" @keydown="test" tabindex="0">
<div ref="test" v-for="item, index in items" :class="{ focus: index === focus }">
<div>{{ item.title }}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ title: "First" },
{ title: "Second" },
{ title: "Third" }
],
focus: null
};
},
methods: {
test: function(event) {
switch (event.keyCode) {
case 38:
if (this.focus === null) {
this.focus = 0;
} else if (this.focus > 0) {
this.focus--;
}
break;
case 40:
if (this.focus === null) {
this.focus = 0;
} else if (this.focus < this.items.length - 1) {
this.focus++;
}
break;
}
}
}
};
</script>
<style>
div.focus {
border: 1px solid blue;
}
</style>
Upvotes: 9