Macro Man Macro Man - 2 months ago 10
Javascript Question

JavaScript to run code when table row loses focus

I have a html table and I'm trying to use javascript to trigger an event whenever a row loses focus but the "blur" event doesn't seem to be right as nothing is firing:

(quick example of what I'm doing)



<tr class="tableRow">
<td class="tg-amwm" contentEditable="true">hours</td>
<td class="tg-amwm" contentEditable="true">minutes</td>
<td class="tg-amwm" contentEditable="true">hours</td>
<td class="tg-amwm" contentEditable="true">minutes</td>
</tr>


and I"m using the following:



var rows = document.getElementsByClassName("tableRow");

for(i = 0; i < rows.length; i++) {
rows[i].addEventListener("blur", function(){console.log("row left!");});
}


but nothing is apprearing in the console - am I misunderstanding the event/DOM structure?

Answer

The row probably never receives focus, the cells in it do.

Unfortunately, blur doesn't bubble. But if you hook blur on each cell, then click one of those cells to give it focus, then click something else to take focus away, it should work:

var cells = document.querySelectorAll(".tableRow td");

for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener("blur", handler);
}

function handler() {
  console.log("row left!");
}
<p>Click a cell below to give it focus</p>
<table>
  <tbody>
    <tr class="tableRow">
      <td class="tg-amwm" contenteditable>hours</td>
      <td class="tg-amwm" contenteditable>minutes</td>
      <td class="tg-amwm" contenteditable>hours</td>
      <td class="tg-amwm" contenteditable>minutes</td>
    </tr>
  </tbody>
</table>
<p>Click here to take focus away</p>

Alternately, use focusout, which was originally an IE-only event but which has been added to Chrome but not, as far as I can tell, Firefox:

document.querySelector("table").addEventListener("focusout", function() {
  console.log("Left!");
});
<p>Click a cell below to give it focus</p>
<table>
  <tbody>
    <tr class="tableRow">
      <td class="tg-amwm" contenteditable>hours</td>
      <td class="tg-amwm" contenteditable>minutes</td>
      <td class="tg-amwm" contenteditable>hours</td>
      <td class="tg-amwm" contenteditable>minutes</td>
    </tr>
  </tbody>
</table>
<p>Click here to take focus away</p>


Side note for jQuery users: jQuery makes focus and blur bubble even though they don't natively, so you could use event delegation for the above with jQuery.