vue.jsvuejs3vue-events

vue 3 key events on table


In vue, i have problem with key events not triggered. I know i can bind listener on body, wonder why does the @keypress not work (i click some row and then try to catch 'ArrowUp','ArrowDown' and some other case keypress events):

<div @keypress="keyEvt($event)">
 <table>
  <tr v-for='(row,k) in pageRows()' :key="k" ref="k" @click="selectRow(row,k)" @mouseover="redrawCss(row.id)" >
    <template v-for="(val,k) in row">
      <td :class="k">{{ val }}</td>
    </template>
  </tr>
 </table>
</div>

and method in app methods:

keyEvt: function(ev){ console.log(ev); }

this never triggers

Only way i know works, is adding listener to body (on mounted)

mounted:function() { document.addEventListener( "keydown", this.keyEvt); }

There are some <tr @click events to select row, but events should bubble up, so even redrawing table rows, parent div sholud still catch the event?

If i use the mounted/body listener solution, i see both srcElement and target to state its catched on 'body' element.

I tried mouse click on row cell, then press arrow on keyboard, it does not get caught by @keypress on table or its parent. Why not? Anyone had the same issue? Are key event only working for input/textare/button types of elements? Is there any specific reason why event triggering on elements in template may stop wo(r)king?

In case of using the event listener on body, even event.srcElement is 'body'. Is that normal? Is that because i dont use input-type element that can be "focused" ?


Solution

  • Have a look at the description for keydown:

    Keyboard events are only generated by <input>, <textarea>, <summary> and anything with the contentEditable or tabindex attribute. If not caught, they bubble up the DOM tree until they reach Document.

    So unless you put an input (or something similar) in your table, key events will not be generated inside it, and @keypress/@keydown/@keyup listeners will never be triggered.