Thanks for all the responses. To the questions, it's a very simple
single page web app with only a half dozen users and I'm also the
primary user/developer/tester.
The context is a text edit widget that manifests inside a spreadsheet-like
table view of personnel scheduling data. Clicking a cell turns the
<td><span/></td> into a <td><input></td> and then onchange or onblur on
the input changes it back to a span.
eg.
https://github.com/luser-dr00g/luser-dr00g.github.io/blob/master/cm-tool.html#L1092
function addGridNotesWidgets(){
let notes = grid.querySelectorAll( ".notes" );
notes.forEach( (note) => {
let idx = note.dataset.index;
const clickHandler = (event) => {
let edit = document.createElement( "input" );
edit.value = global.data[ idx ][5];
//edit.size = 30; // tweak the size or width here?
let target = note.childNodes[0];
note.replaceChild( edit, target );
note.parentNode.removeEventListener( "click", clickHandler );
const done = (event) => {
if( edit.value == "" ) edit.value = "\t";
target.textContent = edit.value;
changeNotes( idx, edit.value );
edit.parentNode.replaceChild( target, edit );
saveData();
output();
};
edit.addEventListener( "change", done );
edit.addEventListener( "blur", done );
edit.focus();
};
note.parentNode.addEventListener( "click", clickHandler );
});
}