The original content of this post involved a little function I wrote called “getNodeHtml”, which basically wrapped a given HTML element with a parent node, got the innerHTML of that temporary parent node, reset the DOM to its previous state, then returned the HTML string. I also used jQuery in the function, which seemed unnecessary to me.

Today I saw that IE has an outerHTML property, which does exactly what I need. I generally avoid giving IE credit, but they get a chocolaty kudos bar for this one.

The Array.indexOf() function I have gave me the idea to extend the prototype of the HTMLElement object so I could have it at my fingertips, and use the same property call in FF and IE (amoung others). After spending some time trying to add a “get outerHTML” property to the HTMLElement object, I found some useful info on Javascript Getters and Setters that pointed me in the right direction. The result…
if(document.__defineGetter__ && !HTMLElement.outerHTML){
HTMLElement.prototype.__defineGetter__(”outerHTML”, function(){
var parent = this.parentNode;
var span = document.createElement(”span”);
span.appendChild(this);
var HTML = span.innerHTML;
parent.appendChild(this);
delete span;
return HTML;
});
}

The __define[SG]etter__ methods do not exist in IE, so I’m still curious how to add a getter/setter to an existing prototype there. We could just create functions like value(’test’, ’set’) / value(null, ‘get’) or setValue(’test’) / getValue(), but bleh…those are methods, not properties.

********************UPDATE************************

I have found that manipulating the DOM momentarily to get the outerHTML of an element can cause some problems when you’re doing alot of DOM manipulation simultaneously. Instead, the following method builds the HTML of the current element by looping through its attributes - much more reliable!

if (document.__defineGetter__ && !HTMLElement.outerHTML) {
    HTMLElement.prototype.__defineGetter__("outerHTML", function(){
        var emptyTags = {
		   "img":   true,
		   "br":    true,
		   "input": true,
		   "meta":  true,
		   "link":  true,
		   "param": true,
		   "hr":    true
		};

		var attrs = this.attributes,
		tagName = this.tagName.toLowerCase(),
		str = "<" + tagName;
		for (var a = 0; a < attrs.length; a++)
		  str += " " + attrs[a].name + "=\"" + attrs[a].value + "\"";

		if (emptyTags[tagName])
		  return str + "/>";

		return str + ">" + this.innerHTML + "";

    });
}