PuffedRiceCrackers
PuffedRiceCrackers

Reputation: 785

Limit effect of keyboard event to a specific component

I have a list on which I implemented keyboard (up/down arrow) navigation.

<template>
   <div ref="listContainer">
    <li>a</li>
    <li>b</li>
    <li>c</li>
   </div>
</template>

<script>
export default {
  mounted() {
    document.addEventListener('keyup', this.nextItem); 
  },
  beforeDestroy() {
    document.removeEventListener('keyup', this.nextItem);
  },
  methods: {
    nextItem(e) {
      // this.nextItem will mark what item in a list are currently shown
    }
  },
}
</script>

The problem is that when this.nextItem gets triggered, the whole page reacts (parents components, etc) to the keyboard input and gets scrolled. A walk-around is to click the target component first and then use keyboard but that I can't expect from users.

Maybe this isn't how it is supposed to be used but I tried Event Modifier to no success

<template>
   <div
    ref="listContainer"
    @keyup.up.prevent="nextItem">
    <li>a</li>
    <li>b</li>
    <li>c</li>
   </div>
</template>

Upvotes: 0

Views: 355

Answers (1)

wilkoklak
wilkoklak

Reputation: 192

You have to use keydown event listener and use e.preventDefault() there.

For example do something like this

 mounted() {
    document.addEventListener('keydown', (e) => {
      if(e.key === 'ArrowUp') {
        e.preventDefault()
        this.goUp()
      } else if(e.key === 'ArrowDown') {
        e.preventDefault()
        this.goDown()
      }
    })
  },

I think that's because the scroll happens on keydown, and not on keyup event.

See an example tested in Edge 85: CodePen

Keep in mind that you have to click inside the frame, because event's will only work on a document that has a focus - by default it's the page, but the example is inside an iframe

Upvotes: 2

Related Questions