When used on a <div> with contenteditable=true after focusing on that element, Safari (15.5) does not appear to handle HTMLElement.blur() normally : it removes the border highlighting the element, but the cursor remains in the element and any keyboard input still falls into that element. In other words, the element seems to partly loses focus, but not entirely. There is no comparable issue in Firefox, which does what I expect - blur() results in entire removal of focus.
function focusInput() {
document.getElementById('realtext').focus();
}
function shouldBlur() {
document.getElementById('realtext').blur();
}
function doesBlur() {
document.getElementById('realtext').blur();
document.getElementById('pretext').setAttribute("contenteditable","true")
document.getElementById('pretext').focus();
document.getElementById('pretext').blur();
document.getElementById('pretext').setAttribute("contenteditable","false")
}
<div id="pretext"></div>
<div type="text" id="realtext" value="Sample Text" contenteditable=true></div>
<br><br>
<button type="button" onclick="focusInput()">Click me to gain focus</button>
<button type="button" onclick="shouldBlur()">Click me to lose Focus on Firefox but not Safari</button>
<button type="button" onclick="doesBlur()">Click me to really lose focus even on Safari 15.5</button>
Is this a bug? The above example suggests a workaround, but is there anything better to do? I am a JS newbie, so I am wondering if such things are usual, it had me losing a lot of time guessing.
Details:
<input> element, such as here: MDN example HTMLElement.blur()document.documentElement.focus() has the same effect as blur() on the element that we wish to remove the focus from (this method is recommended here: html.spec.whatwg.org, and quoted in the MDN page above). It does not solve the problem in Safari.<div>, simply changing the element that should lose focus to contenteditable=false seems to do the job, but if it is set again to true, then the focus comes back! Hence the only way I found is to "distract" Safari with another <div> that does not need to be edited.