JSFiddle - React, Tailwind, and code Playground
by narzantaria
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="h1-trigger">Turn selection</button>
<button id="check">Check selection status</button>
<div id="editor">This is the text where we can select some word by double-clicking, and press the "h1-trigger button". The function wraps the selection with h1 tags. When clicked again it will unwrap the selection and return to previous text. But if we unselect the wrapped word (h1 heading), select by double-click again, and press the button, it does another result. The second button shows the selection status with console log. Why re-selection doesn't contain the created tags?</div>
</body>
</html>
JavaScript
document.getElementById('h1-trigger').addEventListener('click', function () {
headerFormatter();
});
document.getElementById('check').addEventListener('click', function () {
let sel = window.getSelection();
let range = sel.getRangeAt(0).cloneRange();
let rangeProxy = sel.getRangeAt(0).cloneContents();
console.log(sel);
console.log(range);
console.log(rangeProxy);
});
function headerFormatter() {
let newTag = document.createElement('h1');
if (window.getSelection) {
let sel = window.getSelection();
if (sel.rangeCount) {
let range = sel.getRangeAt(0).cloneRange();
// create an object from range for querying tags
let rangeProxy = sel.getRangeAt(0).cloneContents();
if (rangeProxy.querySelector('h1') || rangeProxy.querySelector('h2') || rangeProxy.querySelector('h3')) {
let tagContent = rangeProxy.querySelector('h1').innerHTML;
// compare selection length with queried tag length
if (range.startOffset == 1) {
tagContent = tagContent.replace(/(<([^>]+)>)/ig, "");
range.deleteContents();
range.insertNode(document.createTextNode(tagContent));
sel.removeAllRanges();
sel.addRange(range);
return;
}
else {
let rangeToString = range.toString().replace(/(<([^>]+)>)/ig, "");
range.deleteContents();
range.insertNode(document.createTextNode(rangeToString));
sel.removeAllRanges();
sel.addRange(range);
return;
}
} else {
range.surroundContents(newTag);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
}