Blur Fires Immediately after Focus

The basic issue is elements that get focus lose it immediately. Here’s the requirements in which this is happening:

  1. Data displays in a two-column format.
  2. The user can edit the text in the second column elements.
  3. When the user clicks on an element, the current element should lose focus, enabling me to take some action before the clicked element acquires focus.
  4. The user needs to be able to select text across elements in the second column. That is, selection ranges can include multiple elements from the second column, and excluding the elements in the first column.

The code below illustrates that these requirements are met, except for #3. What happens is that when the user clicks on an element, it acquires focus but immediately loses it. The desired behavior is that it keep focus until the user clicks on another element.

Any guidance on making this work without sacrificing one of the other requirements would be appreciated.

function f(e) {
  console.log("focus: " + e.target.textContent);
}

function b(e) {
  console.log("blur: " + e.target.textContent);
}
#container {
  display: flex;
  flex-direction: column;
}

.s {
  border: 1px solid steelblue;
  height: 20px;
  width: 200px;
}

.ns {
  border: 1px solid steelblue;
  height: 20px;
  width: 200px;
  background-color: lightgray;
  user-select: none;
}

.row {
  display: flex;
  flex-direction: row;
}
<div id="container" contenteditable="true">
  <span class="row">
    <span class="ns" contenteditable="false">No select, no edit</span>
    <span class="s" contenteditable="true" onfocus="f(event)" onblur="b(event)" tabindex="0">1</span>
  </span>
  <span class="row">
    <span class="ns" contenteditable="false">No select, no edit</span>
    <span class="s" contenteditable="true" onfocus="f(event)" onblur="b(event)" tabindex="1">2</span>
  </span>
  <span class="row">
    <span class="ns" contenteditable="false">No select, no edit</span>
    <span class="s" contenteditable="true" onfocus="f(event)" onblur="b(event)" tabindex="2">3</span>
  </span>
  <span class="row">
    <span class="ns" contenteditable="false">No select, no edit</span>
    <span class="s" contenteditable="true" onfocus="f(event)" onblur="b(event)" tabindex="3">4</span>
  </span>
  <span class="row">
    <span class="ns" contenteditable="false">No select, no edit</span>
    <span class="s" contenteditable="true" onfocus="f(event)" onblur="b(event)" tabindex="4">5</span>
  </span>
</div>
%d bloggers like this: