Reputation: 1525
I have a contenteditable p tag. When the content from the p tag is extracted, and inserted into the other tag, all the markup of the original is lost. Is there any way to save the markup?
Please note if the caret is @ the i-th position in the paragraph, then the characters are extracted starting from that position till the end.
function select() {
var el = document.getElementById('p');
el.focus();
var sel = window.getSelection();
var selRange = sel.getRangeAt(0);
var range = selRange.cloneRange();
range.selectNodeContents(el);
range.setStart(selRange.endContainer, selRange.endOffset);
document.getElementById('other').innerHTML = (range.extractContents().textContent);
// return range.extractContents().textContent;
}
p {
background-color: #eee;
}
.red {
color: red;
}
<p id="p" contenteditable="true">This is <i>a</i> <span class="red">paragraph</span> <b>with</b> lots of markup.</p>
<p id="other"></p>
<button onclick="select()">SELECT</button>
Upvotes: 7
Views: 5602
Reputation: 2279
For further reference, If anyone actually need the innerHTML of the extracted fragment.
The fragment have Children Nodes and those have the outerHTML
property, so you simple have to get the outerHTML
from all childNodes
const fragment = range.extractContents();
const htmlContent = [].map.call(fragment.childNodes, x => x.outerHTML).join('')
the map.call
part is needed because although the fragment has the childNodes
property, the childNodes
doesn't have the map
method.
Upvotes: 6
Reputation: 179036
range.extractContents()
returns a DocumentFragment
.
DocumentFragment
doesn't have an innerHTML
property. innerHTML
comes from the Element
interface, while textContent
is part of the Node
interface. DocumentFragment
inherits from Node
, but not Element
.
This means you could just append the entire fragment because it's a Node
:
function select() {
var el = document.getElementById('p');
el.focus();
var sel = window.getSelection();
var selRange = sel.getRangeAt(0);
var range = selRange.cloneRange();
range.selectNodeContents(el);
range.setStart(selRange.endContainer, selRange.endOffset);
//document.getElementById('other').innerHTML = (range.extractContents().textContent);
var frag = range.extractContents();
var i;
var node;
var other = document.getElementById('other');
other.innerHTML = '';
other.appendChild(frag);
}
p {
background-color: #eee;
}
.red {
color: red;
}
<p id="p" contenteditable="true">This is <i>a</i> <span class="red">paragraph</span> <b>with</b> lots of markup.</p>
<p id="other"></p>
<button onclick="select()">SELECT</button>
Upvotes: 7
Reputation: 498
Didn't you mean something like this ?
document.getElementById('other').innerHTML = el.innerHTML;
Your javascript then would be as simple as:
function select() {
var el = document.getElementById('p');
el.focus();
document.getElementById('other').innerHTML = el.innerHTML;
}
EDIT:
Hey, you down voted my answer but can you explan what you want to achieve? The code i wrote above you can see working in this jsfiddle: https://jsfiddle.net/936zuzky/1/
You want to save original markup - it's saved so what do you want to achieve ?
Upvotes: -2