In my example example I like to capture a keydown event inside an editable table:
- Click/select a cell
- Press delete
<!-- index.html -->
<table contenteditable="true">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</table>
When I use for example a simple simple click event it works fine:
//script.js
const tdElements = document.querySelectorAll("td");
function clickHandler(){this.remove()}
tdElements.forEach((item)=>{item.addEventListener("click", this.clickHandler)});
But when I try to catch the delete key event, only the cell gets edited (the keydown event is not catched).
I suppose the reason for this is that the keyevents for editing the cell is overriding my added event listener. How can make the event listener to catch the delete key command?
//script.js
const tdElements = document.querySelectorAll("td");
function keydownHandler() {console.log(event.key)}; //console.log does not work
tdElements.forEach((item)=>{item.addEventListener("keydown", keydownHandler)})
When I simply add the key catcher to the document the key gets logged as expected.
//script.js
function keydownHandler() {console.log(event.key)}; //console.log works fine
document.addEventListener("keydown", keydownHandler)
2
Answers
After investigation I found a way to delete certain cells by selecting and afterwards pressing delete. By adding an event listener to the document it finally works.
Still I dont know why the event listeners don't work for the td-elements.
Problem
You set an event listener for the
keydown
event on all yourtd
elements however these elements don’t generate keyboard events. From MDN documentation:In your case, the
table
element would generate the event. Demo below:Solution
You could add the
tabindex
attribute to each of yourtd
s. This will allow them to emit thekeydown
event. There’s the additional benefit that these are now navigable via the keyboard. Demo below: