Is there a good JS function or class that can seamlessly parse a string of HTML into the DOM without resetting existing content? I'm trying to find an easy way to duplicate a complicated table row at the top of the table.
It obviously will work like this:
element.innerHTML = newHTML + element.innerHTML;
However, this causes the browser to reload the entire table which resets the scroll position and deletes any unsaved editable content in the table.
UPDATE:
I'm not using jQuery for this project. Here's an idea I found somewhere but I cant get it working:
var templateRow = document.getElementById( 'templateRow' );
var newhtml = "<tr id='row"+lastID+"'>"+'templateRow'.innerHTML+"</tr>";
var range = document.createRange();
range.selectNode( 'templateRow' );
var parsedHTML = range.createContextualFragment( newhtml );
templateRow.appendChild( parsedHTML )
Best Answer
Are you attempting to insert content into an existing element, without disturbing the content that's already in there?
The most straightforward answer is
insertAdjacentHTML
. This is an IE scripting extension, since standardised by HTML5:Unfortunately it is not implemented everywhere. So elsewhere you have to create a new element, set
innerHTML
on it and then transfer the contents to the target:If you have a lot of new content, this will be slow. You can speed it up on browsers that support DOM Range by making a Range over the new content, extracting it to a DocumentFragment and inserting that fragment into the target node in one go.
Unfortunately (again), whether you are using
insertAdjacentHTML
orinnerHTML
, there are elements that IE<9 won't set HTML on: most notably<table>
and its relations. So in that case you have to surround the HTML in a suitable wrapper for the element name:and then extract the contents from the inner element to put in the target.
The good thing about this is that with tables if you have a lot of new rows you can put them in a single
<tbody>
andinsertBefore
/appendChild
that body to put all the rows in in one go, which is quicker than one-by-one.