Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InnerHTML append instead of replacing

I'm using this code to update a div with an AJAX request

var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        document.getElementById("some_id").innerHTML += xmlhttp.responseText;
    }
}
xmlhttp.open("GET", "http://example.com/");
xmlhttp.setRequestHeader('Content-Type', 'utf8');
xmlhttp.send();

Everything works fine, the problem is that when the div with id some_id has a lot of content in it i can see the content disappearing and then appearing updated after the AJAX request has been executed.

I think that it's because

document.getElementById("some_id").innerHTML += xmlhttp.responseText;

Is deleting and replacing the innerHTML of the div with the previous innerHTML plus the new content, resulting in a previous content → blank → updated content behaviour.

Is there a way to append the new content to the div instead of replacing its whole content with the new one?

like image 400
BackSlash Avatar asked Aug 30 '13 19:08

BackSlash


3 Answers

Assuming that htmlhttp.responseText is a node:

document.getElementById("some_id").appendChild(xmlhttp.responseText);

If you have only a string of HTML (which seems likely), then:

var newElement = document.createElement('div');
newElement.innerHTML = xmlhttp.responseText;
document.getElementById("some_id").appendChild(newElement);

On the other hand, if you must append new elements from a string:

// getting a reference to the relevant element we're adding to:
var container = document.getElementById("some_id"),
    // creating a new element to contain the 'xmlhttp.responseText'
    newElement = document.createElement('div');
// setting the innerHTML of the 'newElement' to whatever 'xmlhttp.responseText' is:
newElement.innerHTML = xmlhttp.responseText;

/* (repeatedly) removing the firstChild, and appending it to the 'container',
   of the 'newElement' until it's empty: */
while (newElement.firstChild) {
    container.appendChild(newElement.firstChild);
}
// removing the now empty 'newElement':
newElement.parentNode.removeChild(newElement);

References:

  • Node.appendChild().
like image 151
David Thomas Avatar answered Oct 06 '22 06:10

David Thomas


You could use Element.insertAdjacentHTML().

insertAdjacentHTML() parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position. It does not reparse the element it is being used on and thus it does not corrupt the existing elements inside the element. This, and avoiding the extra step of serialization make it much faster than direct innerHTML manipulation.

I guess you would do

const div = document.getElementById("some_id");
div.insertAdjacentHTML('beforeend', xmlhttp.responseText);;
like image 36
oldergod Avatar answered Oct 06 '22 05:10

oldergod


old_html = document.getElementById("some_id").innerHTML;
document.getElementById("some_id").innerHTML = old_html+xmlhttp.responseText;
like image 4
Ankit Agrawal Avatar answered Oct 06 '22 05:10

Ankit Agrawal