I'm looking for function which allows me to build some element before or after selected text. Something similar like this one javascript replace selection all browsers but for adding some content before or after selection instead of replacing it, like after()
and before()
jQuery methods. Should I use some DOM selection method, if yes which one? Or does exist something easier to carry it out?
Here's a pair of functions to do this.
Live example: http://jsfiddle.net/hjfVw/
Code:
var insertHtmlBeforeSelection, insertHtmlAfterSelection;
(function() {
function createInserter(isBefore) {
return function(html) {
var sel, range, node;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = window.getSelection().getRangeAt(0);
range.collapse(isBefore);
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
}
} else if (document.selection && document.selection.createRange) {
// IE < 9
range = document.selection.createRange();
range.collapse(isBefore);
range.pasteHTML(html);
}
}
}
insertHtmlBeforeSelection = createInserter(true);
insertHtmlAfterSelection = createInserter(false);
})();
In MSIE: collapse the given range and the use pasteHTML to insert the element
Others: Also collapse the given Range and insert the element via insertNode
Both collapse-methods accept an optional argument which defines to where you want to collapse to. If you want to put the element at the end, collapse to the end, otherwise to the start.
function yourFunction() {
const sel = window.getSelection ? window.getSelection() : document.selection.createRange()
if (!sel) return false
if (sel.getRangeAt) {
const range = sel.getRangeAt(0)
const text = range.toString()
console.log(text)
range.deleteContents()
range.insertNode(document.createTextNode(`before text${text}after`))
} else {
sel.pasteHTML(`[s=спойлер]${sel.htmlText}after`)
}
}
JS in 2024 Update
Use the .after()
& before()
method of your node. Here is an example:
const p = document.querySelector(".paragraph-1")
let container = document.createElement("div");
container.innerHTML = "NEWLY ADDED ELEMENT"
p.after(container)
Demo:
function addElementAfter(){
const span = document.querySelector(".selection")
let container = document.createElement("div");
container.innerHTML = "How are you doing?"
span.after(container)
}
<div>
<p>Hello <span class="selection">world!</span> </p>
</div>
<button onclick="addElementAfter()">Add content</button>
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Element/after
alternative method (insertAdjacentElement)
A second option is using the insertAdjacentElement(position, element)
method: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement
<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->
© 2022 - 2024 — McMap. All rights reserved.