views:

292

answers:

7

Hi,

Imagine I have the following HTML:

<div><span><b>This is in bold</b></span></div>

I want to get the HTML for the div, including the div itself. Element.innerHTML only returns:

<span>...</span>

Any ideas? Thanks

A: 

First, put on element that wraps the div in question, put an id attribute on the element and then use getElementById on it: once you've got the lement, just do 'e.innerHTML` to retrieve the HTML.

<div><span><b>This is in bold</b></span></div>

=> <div id="wrap"><div><span><b>This is in bold</b></span></div></div>

and then:

var e=document.getElementById("wrap");
var content=e.innerHTML;

Note that outerHTML is not cross-browser compatible.

jldupont
Did you actually read the question? :)
Jørn Schou-Rode
yes I read the question... did you read my answer?
jldupont
the problem with getting the innerHTML for the div's parent is that I'll also get the innerHTML for the div's siblings
Richard
My bad, I thought the "put an id attribute on the element" referred to "the element". With your last edit it is a lot clearer that you want to add an additional `div` to the soup :)
Jørn Schou-Rode
There's no need to put it into the document...
J-P
What's that down-vote about???
jldupont
@J-P: if the element is not in the `document`... then where is it, do you care to enlighten us all?
jldupont
@J-P: of course you can create elements where you want but this is **no** reason for a down-vote... you won't make much friends around here with that sort of attitude.
jldupont
A: 
var el = document.getElementById('foo');
el.parentNode.innerHTML;
Jason Leveille
this will also give me any html for the div's siblings though right?
Richard
That's true. Good point.
Jason Leveille
What's up with the down vote? The original question had nothing to do with siblings. This answer was a perfectly valid answer given the original context of the question.
Jason Leveille
On the other hand, the original question had nothing to do with a parent. So, whatever.
Jason Leveille
A: 

Use outerHTML:

var el = document.getElementById( 'foo' );
alert( el.outerHTML );
Majkel
is this cross-browser??
jldupont
No it's an IE extension. Although there exist Firefox workarounds: http://snipplr.com/view/5460/outerhtml-in-firefox/
Wim
Hmm, not sure - it certainly works in Opera and IE.
Majkel
this is certainly what I need.. although apparently is an IE extension. Am in a WebKit environment - testing now. thanks
Richard
WebKit based browsers seem to support it, but Firefox doesn't.
Jørn Schou-Rode
According to http://www.quirksmode.org/dom/w3c_html.html it should work in IE, Opera, Safari and Chrome.
Majkel
my webkit implementation of outerHTML seems to just return the string content, and not html. innerHTML works as expected.
Richard
Note that outerHTML is part of HTML5, and so should be supported by everyone in time.
Xanthir
+1  A: 

as outerHTML is IE only, use this function:

function getOuterHtml(node) {
    var parent = node.parentNode;
    var element = document.createElement(parent.tagName);
    element.appendChild(node);
    var html = element.innerHTML;
    parent.appendChild(node);
    return html;
}

creates a bogus empty element of the type parent and uses innerHTML on it and then reattaches the element back into the normal dom

Zenon
+1  A: 

You'll want something like this for it to be cross browser.

function OuterHTML(element) {
    var container = document.createElement("div");
    container.appendChild(element.cloneNode(true));

    return container.innerHTML;
}
Nikolas Stephan
This would remove `element` from the document when called, right?
Jørn Schou-Rode
It would, have fixed that now by adding cloneNode, which makes it pretty much identical to some of the other answers here.
Nikolas Stephan
+4  A: 

Expanding on jldupont's answer, you could create a wrapping element on the fly:

var target = document.getElementById('myElement');
var wrap = document.createElement('div');
wrap.appendChild(target.cloneNode(true));
alert(wrap.innerHTML);

I am cloning the element to avoid having to remove and reinsert the element in the actual document. This might be expensive if the element you wish to print has a very large tree below it, though.

Jørn Schou-Rode
hi - on balance this is probably my best option. a little wary of detaching/attaching elements, I can't screw up the DOM, and I do not expect there to be large trees.
Richard
+1 for excellent but under-used cloneNode
bobince
I love how the best answers are usually the simplest.
jathanism
+2  A: 

If you want a lighter footprint, but a longer script, get the elements innerHTML and only create and clone the empty parent-

function getHTML(who,lines){
    if(!who || !who.tagName) return '';

    var txt, ax, str, el= document.createElement('div');
    el.appendChild(who.cloneNode(false));
    txt= el.innerHTML;
    ax= txt.indexOf('>')+1;
    str= txt.substring(0, ax)+who.innerHTML+ txt.substring(ax);

    el= null;
    return lines? str.replace(/> *</g,'>\n<'): str;
    //easier to read if elements are separated
}
kennebec
ooh nice touch thanks
Richard