dorado
dorado

Reputation: 1525

Get innerHTML of #document-fragment instead of textContent

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

Answers (3)

Victor Ivens
Victor Ivens

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

zzzzBov
zzzzBov

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

Damian Bartosik
Damian Bartosik

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

Related Questions