Skip to content

Instantly share code, notes, and snippets.

@mzechmeister
Last active October 10, 2021 00:58
Show Gist options
  • Save mzechmeister/1850195893789f47561215dc441c8ddf to your computer and use it in GitHub Desktop.
Save mzechmeister/1850195893789f47561215dc441c8ddf to your computer and use it in GitHub Desktop.
contenteditable with zwsp simple
<!DOCTYPE html>
<html>
<style>
div {background-color: #dfd}
span {background-color: #fbb}
span:nth-child(even) {background-color: #ccf}
input {width:90%; font-size: 11px}
#editable:focus-within, .active {outline: 5px auto Highlight;
outline: 5px auto -webkit-focus-ring-color;
}
</style>
<body>
This is simple and works smoothly in firefox and android chrome.<br>
It uses <code>onselectionchange</code> to mark active spans in <code>contenteditable</code>.
<div id="editable" contenteditable
onmouseenter="zwsp_put(event.target)"><span>00000</span><span>11111</span><br>22222<br><span>44444</span>55555 5555<br>77777<span>88888</span>99999<br>11111<span>22222</span><span>33333</span>44444<br>66666 66666 <span>88888</span><br>
</div>
<p id="demo"></p>
<script>
document.onselectionchange = (e) => {
mark_active(e)
}
var sel = window.getSelection()
var foc
function mark_active(e) {
// highlight the span with caret
foc && foc.classList.remove('active')
if (!editable.contains(sel.focusNode.parentElement)) return
foc = sel.focusNode.parentElement
foc.classList.add("active")
}
function zwsp_put(d){
// insert zwsp only where needed (span-span, etc.)
var zwsp = "&ZeroWidthSpace;" // "&#8203;"
var xleft = "SPAN"
for (x of [...d.childNodes]) {
if ({SPANSPAN:1, SPANBR:1, BRSPAN:1}[xleft+x.tagName]) x.outerHTML = zwsp + x.outerHTML
xleft = x.tagName
}
if (xleft=="SPAN" || xleft=="BR") x.outerHTML += zwsp
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment