<p>
Edit the text. Text between forward slashes gets grouped together so that eg vue components can be attached and styling can be done
</p>
<div contenteditable="true" id="editor"><span class="pretty">First</span>/<span class="pretty">Second</span></div>
var editor = document.querySelector('#editor');
var btn1 = document.querySelector('#button-1');
var btn2 = document.querySelector('#button-2');
function charsInElm(elm) {
return elm.textContent.length;
}
// Recursive visitor/walker
function walk(node, func) {
var stop = func(node); // Return true to stop exit out of the recursion
var children = node.childNodes;
for (var i = 0; !stop && i < children.length; i++) // Children are siblings to each other
if (walk(children[i], func)) return true;
return stop;
}
function saveSelection() { // Counts the number of characters left of the cursor
var r = window.getSelection().getRangeAt(0);
if (r == null) return 0;
var count = 0;
walk(editor, (elm) => {
if (elm.nodeType === Node.TEXT_NODE) {
if (elm !== r.endContainer) {
count += elm.textContent.length;
} else {
count += r.endOffset;
return true;
}
}
return false;
}, 0)
return count;
}
function findChildWithCharIndex(charIndex) {
var child = editor.firstChild,
charCount = 0;
walk(editor, (elm) => {
if (elm.nodeType === Node.TEXT_NODE) {
if (charCount + elm.textContent.length < charIndex) {
charCount += elm.textContent.length;
} else {
child = elm;
return true;
}
}
return false;
});
return {
child,
offsetInChild: charIndex - charCount
}
}
function restoreSelection(savedRange) {
if (!savedRange) return;
editor.focus();
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
var {
child,
offsetInChild
} = findChildWithCharIndex(savedRange);
if (child) {
var r = document.createRange();
r.setStart(child, offsetInChild);
r.setEnd(child, offsetInChild);
s.addRange(r);
}
}
var keyUpHandler = () => {
var contents = editor.textContent;
var tokens = contents.split('/');
var range = saveSelection();
while (editor.firstChild) {
...
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.