152

I wish to get the entire html of a selected element not just it's contents. .html() uses javascripts innerHTML() method according to the documentation. HTML:

<div id="divs">
  <div id="div1">
    <p>Some Content</p>
  </div>
  <div id="div2">
    <p>Some Content</p>
  </div>
</div>

Using $('#divs:first').html(); will return just the paragraph element. I want to get the html for the whole element, like so:

  <div id="div1">
    <p>Some Content</p>
  </div>

I can't use .parent because this will return html of both child divs.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Benbob
  • 13,876
  • 18
  • 79
  • 114

4 Answers4

222

You can clone it to get the entire contents, like this:

var html = $("<div />").append($("#div1").clone()).html();

Or make it a plugin, most tend to call this "outerHTML", like this:

jQuery.fn.outerHTML = function() {
  return jQuery('<div />').append(this.eq(0).clone()).html();
};

Then you can just call:

var html = $("#div1").outerHTML();
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 8
    This is a great answer, but it really sucks that jQuery doesn't implement its own method. – Philip Walton Apr 05 '11 at 07:51
  • 6
    It is not perfect. In case HTML has a `script` tag the code from this tag will run when `append` is called. It might cause problems. – Andrej Feb 13 '14 at 16:17
135

Differences might not be meaningful in a typical use case, but using the standard DOM functionality

$("#el")[0].outerHTML

is about twice as fast as

$("<div />").append($("#el").clone()).html();

so I would go with:

/* 
 * Return outerHTML for the first element in a jQuery object,
 * or an empty string if the jQuery object is empty;  
 */
jQuery.fn.outerHTML = function() {
   return (this[0]) ? this[0].outerHTML : '';  
};
zb226
  • 9,586
  • 6
  • 49
  • 79
Pasi Jokinen
  • 1,685
  • 1
  • 10
  • 8
  • And if you just want the opening tag: `/<[^>]+>/.exec(elem[0].outerHTML)[0]` – z0r Nov 19 '14 at 02:23
  • 1
    I also like the defaulting to empty string instead of allowing null reference errors, nice and short and sweet and stable, thank you. This works great for me. – OG Sean Feb 20 '18 at 22:15
  • Upvoting for standard DOM functionality, and twice as fast :) – saricden Jun 29 '18 at 10:59
38

You can achieve that with just one line code that simplify that:

$('#divs').get(0).outerHTML;

As simple as that.

Juan Antonio
  • 2,451
  • 3
  • 24
  • 34
Shakti Shakya
  • 399
  • 3
  • 5
  • Because I'm in the situation with puppeteer, where jquery plugin is not very convenient, however this one line style is exactly suitable for puppeteer/phantomjs-like scrapping script. – 千木郷 Oct 26 '18 at 06:52
3

You can easily get child itself and all of its decedents (children) with Jquery's Clone() method, just

var child = $('#div div:nth-child(1)').clone();  

var child2 = $('#div div:nth-child(2)').clone();

You will get this for first query as asked in question

<div id="div1">
     <p>Some Content</p>
</div>
Airy
  • 5,484
  • 7
  • 53
  • 78