SoFunction
Updated on 2025-04-07

Firefox outerHTML implementation code

Reducing the number of DOMs can speed up the browser's construction of DOM Tree and render tree during the parsing of pages, thereby improving page performance. To this end, we can temporarily store the HTML invisible part of the page that is rendered on the first screen in TextArea, and then process this part of the HTML after the rendering is completed to achieve this goal. To add the temporary HTML content in TextArea to the page, it is the easiest and most convenient to use the outerHTML attribute of the element. However, outerHTML is not defined in the DOM standard. Supported browsers include IE6+, safari, operating and Chrome. After testing, it is not supported in FF4.0-. So let's implement an outerHTML that can cross browsers.
outerHTML is to get or set html including the element tag itself. Here is the implementation code:

Copy the codeThe code is as follows:

if(typeof HTMLElement !== "undefined" && !("outerHTML" in )) {
//("defined outerHTML");
.__defineSetter__("outerHTML",function(str){
var fragment = ();
var div = ("div");
= str;
for(var i=0, n = ; i<n; i++){
([i]);
}
(fragment, this);
});
//
.__defineGetter__("outerHTML",function(){
var tag = ;
var attributes = ;
var attr = [];
//for(var name in attributes){//Transfer members on the prototype chain
for(var i=0,n = ; i<n; i++){//nSpecified number of attributes
if(attributes[i].specified){
(attributes[i].name + '="' + attributes[i].value + '"');
}
}
return ((!!) ?
'<' + tag + ' ' + (' ')+'>'++'</'+tag+'>' :
'<' + tag + ' ' +(' ')+'/>');
});
}

Code description:
1 The code first determines the condition to monitor whether the browser supports outerHTML to avoid overwriting the browser's native implementation.
2 "__defineSetter__", "__defineGetter__" is a private aspect of the firefox browser. Define the operations to be performed when setting the attribute value and obtaining the attribute.
3 In "__defineSetter__" "outerHTML", in "__defineSetter__" "outerHTML", in order to avoid frequent reflow affecting performance. The document fragment object fragment is used to temporarily store the DOM elements that need to be inserted into the page.
4 Use the element attributes attributes in "__defineGetter__" "outerHTML" to traverse the attributes specified for the element. Combined with innerHTML, an html string containing the original attribute itself is returned.
Test code:
Copy the codeThe code is as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>outerHTML</title>
</head>
<body>
<div class="test">
<p>This is <strong>paragraph</strong> with a list following it</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
<script>
if(typeof HTMLElement !== "undefined" && !("outerHTML" in )) {
("defined outerHTML");
.__defineSetter__("outerHTML",function(str){
var fragment = ();
var div = ("div");
= str;
for(var i=0, n = ; i<n; i++){
([i]);
}
(fragment, this);
});
//
.__defineGetter__("outerHTML",function(){
var tag = ;
var attributes = ;
var attr = [];
//for(var name in attributes){//Transfer members on the prototype chain
for(var i=0,n = ; i<n; i++){//nSpecified number of attributes
if(attributes[i].specified){
(attributes[i].name + '="' + attributes[i].value + '"');
}
}
return ((!!) ?
'<' + tag + ' ' + (' ')+'>'++'</'+tag+'>' :
'<' + tag + ' ' +(' ')+'/>');
});
}
var content = ("content");
alert()
</script>
</body>
</html>

Suppose you want to get the outerHTML of <p>sdfdsd</p>
Code:
Copy the codeThe code is as follows:

var _p = ('outerID');
_P = _P.cloneNode();
var _DIV = ();
_DIV.appendChild(_P);
alert(_DIV.innerHTML); is P's outerHTML;

Firefox does not have outerHTML to solve it with the following method
Copy the codeThe code is as follows:

/**
* Firefox-compatible outerHTML After using the following code, firefox can use
**/
if() {
.__defineSetter__("outerHTML",function(sHTML){
var r=();
(this);
var df=(sHTML);
(df,this);
return sHTML;
});
.__defineGetter__("outerHTML",function(){
var attr;
var attrs=;
var str="<"+();
for(var i=0;i<;i++){
attr=attrs[i];
if()
str+=" "++'="'++'"';
}
if(!)
return str+">";
return str+">"++"</"+()+">";
});
.__defineGetter__("canHaveChildren",function(){
switch(()){
case "area":
case "base":
case "basefont":
case "col":
case "frame":
case "hr":
case "img":
case "br":
case "input":
case "isindex":
case "link":
case "meta":
case "param":
return false;
}
return true;
});
}

The test works.
New solution to insertAdjacentHTML compatibility
Copy the codeThe code is as follows:

//----Insert html code at the end of the component
function InsertHtm(op,code,isStart){
if(Dvbbs_IsIE5)
(isStart ? "afterbegin" : "afterEnd",code);
else{
var range=();
(op);
var fragment = (code);
if(isStart)
(fragment,);
else
(fragment);
}
}

References about inner/outerHTML in NC6
DOM level 1 has no methods to allow for insertion of unparsed HTML into the document tree (as IE allows with insertAdjacentHTML or assignment to inner/outerHTML).NN6 (currently in beta as NN6PR3) know supports the .innerHTMLproperty of HTMLElements so that you can read or write the innerHTML of a page element like in IE4+.NN6 also provides a DOM level 2 compliant Range object to which a createContextualFragment('html source string')was added to spare DOM scripters the task of parsing html and creating DOM create a Range with var range = ();Then you should set its start point to the element where you want to insert the html for instance var someElement = ('elementID'); (someElement);Then you create a document fragment from the html source to insert for example var docFrag = ('<P>Kibology for all.</P>');and insert it with DOM methods (docFrag);The Netscape JavaScript 1.5 version even provides so called setters for properties which together with the ability to prototype the DOM elements allows to emulate setting of outerHMTL for NN6:<SCRIPT LANGUAGE="JavaScript1.5">if ( == 'Netscape') { setter = function (html) { = html; var range = (); (this); var docFrag = (html); (docFrag, this); }}</SCRIPT> If you insert that script block you can then write cross browser code assigning to .innerHTML .outerHTMLfor instance = '<P>Scriptology for all</P>';which works with both IE4/5 and following provides getter functions for .outerHTMLto allow to read those properties in NN6 in a IE4/5 compatible way. Note that while the scheme of traversing the document tree should point you in the right direction the code example might not satisfy your needs as there are subtle difficulties when trying to reproduce the html source from the document tree. See for yourself whether you like the result and improve it as needed to cover other exceptions than those handled (for the empty elements and the textarea element).<HTML><HEAD><STYLE></STYLE><SCRIPT LANGUAGE="JavaScript1.5">var emptyElements = { HR: true, BR: true, IMG: true, INPUT: true};var specialElements = { TEXTAREA: true}; getter = function () { return getOuterHTML (this);}function getOuterHTML (node) { var html = ''; switch () { case Node.ELEMENT_NODE: html += '<'; html += ; if (!specialElements[]) { for (var a = 0; a < ; a++) html += ' ' + [a].() + '="' + [a].nodeValue + '"'; html += '>'; if (!emptyElements[]) { html += ; html += '<\/' + + '>'; } } else switch () { case 'TEXTAREA': for (var a = 0; a < ; a++) if ([a].() != 'value') html += ' ' + [a].() + '="' + [a].nodeValue + '"'; else var content = [a].nodeValue; html += '>'; html += content; html += '<\/' + + '>'; break; } break; case Node.TEXT_NODE: html += ; break; case Node.COMMENT_NODE: html += '<!' + '--' + + '--' + '>'; break; } return html;}</SCRIPT></HEAD><BODY><A HREF="javascript: alert(); void 0">show </A>|<A HREF="javascript: alert(); void 0">show </A>|<A HREF="javascript: alert(); void 0">show </A>|<A HREF="javascript: alert(); void 0">show </A><FORM NAME="formName"><TEXTAREA NAME="aTextArea" ROWS="5" COLS="20"> for all.</TEXTAREA></FORM><DIV><P></P><BLOCKQUOTE>Kibology for all.<BR>All for Kibology.</BLOCKQUOTE></DIV></BODY></HTML>Note that the getter/setter feature is experimental and its syntax is subject to change.
setter = function (str) { var r = (); (this); (); var df = (str); (df); return str;} setter = function (str) { var r = (); (this); var df = (str); (df, this); return str;}
getter = function () { return getInnerHTML(this);}
function getInnerHTML(node) { var str = ""; for (var i=0; i<; i++) str += getOuterHTML((i)); return str;}
getter = function () { return getOuterHTML(this)}
function getOuterHTML(node) { var str = ""; switch () { case 1: // ELEMENT_NODE str += "<" + ; for (var i=0; i<; i++) { if ((i).nodeValue != null) { str += " " str += (i).nodeName; str += "=\""; str += (i).nodeValue; str += "\""; } }
if ( == 0 && leafElems[]) str += ">"; else { str += ">"; str += getInnerHTML(node); str += "<" + + ">" } break; case 3: //TEXT_NODE str += ; break; case 4: // CDATA_SECTION_NODE str += "<![CDATA[" + + "]]>"; break; case 5: // ENTITY_REFERENCE_NODE str += "&" + + ";" break;
case 8: // COMMENT_NODE str += "<!--" + + "-->" break; }
return str;}
var _leafElems = ["IMG", "HR", "BR", "INPUT"];var leafElems = {};for (var i=0; i<_leafElems.length; i++) leafElems[_leafElems[i]] = true;
Then we can seal it as a JS reference
if (/Mozilla\/5\.0/.test()) ('<script type="text/javascript" src=""></sc' + 'ript>');
Copy the codeThe code is as follows:

<script language="JavaScript" type="Text/JavaScript">
<!--
var emptyElements = { HR: true, BR: true, IMG: true, INPUT: true }; var specialElements = { TEXTAREA: true };
getter = function() {
return getOuterHTML(this);
}
function getOuterHTML(node) {
var html = '';
switch () {
case Node.ELEMENT_NODE: html += '<'; html += ; if (!specialElements[]) {
for (var a = 0; a < ; a++)
html += ' ' + [a].() + '="' + [a].nodeValue + '"';
html += '>';
if (!emptyElements[]) {
html += ;
html += '<\/' + + '>';
}
} else
switch () {
case 'TEXTAREA': for (var a = 0; a < ; a++)
if ([a].() != 'value')
html
+= ' ' + [a].() + '="' + [a].nodeValue
+ '"';
else
var content = [a].nodeValue;
html += '>'; html += content; html += '<\/' + + '>'; break;
} break;
case Node.TEXT_NODE: html += ; break;
case Node.COMMENT_NODE: html += '<!' + '--' + + '--' + '>'; break;
}
return html;
}
//-->
</script>