javascriptjqueryhtmldomdom-node

Find And Change Element In a Parsed HTML DOM


I am getting an HTML string in response to an ajax request. It is a large HTML string with a lot of hierarchical child nodes.

I parse it using

jQuery.parseHTML();

to convert it into a DOM. Now i want to change the content of a child node with a certain ID and then regenerate the HTML.

The Problem is when ever i use a jQuery method to select a dom element to make the changes, it returns that particular node and the

jQuery.html() 

just changes that node to HTML.

I have tried following code samples

 var parsedHTML = jQuery.parseHTML( 'htmlstring' );
 jQuery(parsedHTML).find('#element-id').text('changed text').html();

or

jQuery(parsedHTML).filter('#element-id').text('changed text').html();

the problem is it only returns span#element-id and when html() is applied, the generated html has only span text.

How can i generate back the complete html and change the specific node?


Solution

  • Don't chain (or if you do, use end, but simpler really just not to). By chaining, you're saying you only want the HTML of the last set of elements in the chain:

    var elements = jQuery(parsedHTML);
    elements.filter('#element-id').text('changed text');
    var html = elements.html();
    

    But elements.html() will only give you the inner HTML of the first element. To get the full HTML string again, you need to get the outer HTML of each element and join them together:

    var html = elements.map(function() {
      return this.outerHTML;
    }).get().join("");
    

    Note that your use of filter assumes the element is at the top level of the HTML string. If it is, great, that's fine. If it isn't, you'll want find instead.

    Example with filter:

    var parsedHTML = jQuery.parseHTML(
      "<span>no change</span>" +
      "<span id='element-id'>change me</span>" +
      "<span>no change</span>"
    );
    var elements = jQuery(parsedHTML);
    elements.filter('#element-id').text('changed text');
    console.log(elements.map(function() {
      return this.outerHTML;
    }).get().join(""));
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    Example with find:

    var parsedHTML = jQuery.parseHTML(
      "<span>no change</span>" +
      "<div>the span is in here<span id='element-id'>change me</span></div>" +
      "<span>no change</span>"
    );
    var elements = jQuery(parsedHTML);
    elements.find('#element-id').text('changed text');
    console.log(elements.map(function() {
      return this.outerHTML;
    }).get().join(""));
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>