How do I do OuterHTML in firefox?

Part of my code I get the OuterHTML propery

"<LI onclick="TabClicked(this, 'SearchName', 'TabGroup1');">Name "

so I can do stuff involing parsing it.

There is no OuterHTML property in javascript on firefox though and I can't find an alternative way to get this string. Ideas?

Answers:

Answer

Here's the function we use in pure.js:

function outerHTML(node){
    return node.outerHTML || new XMLSerializer().serializeToString(node);
}

To use it the DOM way:

outerHTML(document.getElementById('theNode'));

And it works cross browsers

EDIT: WARNING! There is a trouble with XMLSerializer, it generates an XML(XHTML) string.
Which means you can end up with a tags like <div class="team" /> instead of
<div class="team"></div>
Some browsers do not like it. I had some pain with Firefox 3.5 recently.

So for our pure.js lib we came back to the old and safe way:

function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one
  return node.outerHTML || (
      function(n){
          var div = document.createElement('div'), h;
          div.appendChild( n.cloneNode(true) );
          h = div.innerHTML;
          div = null;
          return h;
      })(node);
  }
Answer

The proper approach (for non-IE browsers) is:

var sOuterHTML = new XMLSerializer().serializeToString(oElement);
Answer

If you are willing to use jQuery then it's relatively simple:

$('<div>').append( $(ElementSelector).clone() ).html();

This will get the outer HTML of multiple elements if multiple elements are selected.

Answer

For the reason that W3C does not include outerHTML property, you just need add following:

if (typeof (HTMLElement) != "undefined" && !window.opera)  
{  
    HTMLElement.prototype._____defineGetter_____("outerHTML", function()  
    {  
        var a = this.attributes, str = "<" + this.tagName, i = 0; for (; i < a.length; i++)  
            if (a[i].specified)  
            str += " " + a[i].name + '="' + a[i].value + '"';  
        if (!this.canHaveChildren)  
            return str + " />";  
        return str + ">" + this.innerHTML + "</" + this.tagName + ">";  
    });  
    HTMLElement.prototype._____defineSetter_____("outerHTML", function(s)  
    {  
        var r = this.ownerDocument.createRange();  
        r.setStartBefore(this);  
        var df = r.createContextualFragment(s);  
        this.parentNode.replaceChild(df, this);  
        return s;  
    });  
    HTMLElement.prototype._____defineGetter_____("canHaveChildren", function()  
    {  
        return !/^(area|base|basefont|col|frame|hr|img|br|input|isindex|link|meta|param)$/.test(this.tagName.toLowerCase());   
    });  
} 
Answer

Try this: http://snipplr.com/view/5460/outerhtml-in-firefox/:

if (document.body.__defineGetter__) { 
   if (HTMLElement) {
      var element = HTMLElement.prototype;
      if (element.__defineGetter__) {
         element.__defineGetter__("outerHTML",
           function () {
              var parent = this.parentNode;
              var el = document.createElement(parent.tagName);
              el.appendChild(this);
              var shtml = el.innerHTML;
              parent.appendChild(this);
              return shtml;
           }
         );
      }
   }
}
Answer

How about something simple like this (not fully tested):

function outerHTML(node) {
    var el;
    if (node.outerHTML) {
        return node.outerHTML;
    } else if (node.parentNode && node.parentNode.nodeType == 1) {
        var el = document.createElement(node.parentNode.nodeName);
        el.appendChild( node.cloneNode(true) );
        return el.innerHTML;
    }
    return "";
}
Answer

Try:

(function(ele, html)
{if (typeof(ele.outerHTML)=='undefined')
    {var r=ele.ownerDocument.createRange();
     r.setStartBefore(ele);
     ele.parentNode.replaceChild(r.createContextualFragment(html), ele);
    }
 else
     {ele.outerHTML=html;
     }
})(aEle, aHtml);

for diyism

Answer

If all you want is the onclick attribute, then try the following: This assumes that you did not set the event using attachEvent or addEventListener.

elm.getAttribute("onclick");

If you want to make an outerHTML string (just promise not to take it apart after you make it):

function outerHTML(elm){
  var ret = "<"+elm.tagName;
  for(var i=0; i<elm.attributes.length; i++){
    var attr = elm.attributes[i];
    ret += " "+attr.name+"=\""+attr.nodeValue.replace(/"/, "\"")+"\"";
  }
  ret += ">";
  ret += elm.innerHTML+"</"+elm.tagName+">";
  return ret;
}

This function should do the trick in most cases, but it does not take namespaces into account.

Answer

Figured it out!

child.getAttributeNode("OnClick").nodeValue;

getAttribute didn't work, but getAttributeNode worked great ;D

Answer

outerHTML is now supported by Firefox:

From Firefox 11 for developers

Firefox 11 shipped on March 13, 2012. This article provides information about the new features and key bugs fixed in this release, as well as links to more detailed documentation for both web developers and add-on developers.

  • The element.outerHTML property is now supported on HTML elements.
Answer

I know this is an old thread but if anyone finds this with Google (like I did) - I tried all these solutions and none of them worked out-of-the-box, since none handled both the getting and setting properties of outerHTML. I found this: which worked for me:

// Implement the outerHTML property for browsers that don't support it.
// Assumes that the browser does support innerHTML, has an extensible 
// Element.prototype, and allows getters and setters to be defined.
(function() {
// If we already have outerHTML return without doing anything
if (document.createElement("div").outerHTML) return;

// Return the outer HTML of the element referred to by this
function outerHTMLGetter() {
    var container = document.createElement("div"); // Dummy element
    container.appendChild(this.cloneNode(true));   // Copy this to dummy
    return container.innerHTML;                    // Return dummy content
}

// Set the outer HTML of the this element to the specified value
function outerHTMLSetter(value) {
    // Create a dummy element and set its content to the specified value
    var container = document.createElement("div");
    container.innerHTML = value;
    // Move each of the nodes from the dummy into the document
    while(container.firstChild)  // Loop until container has no more kids
        this.parentNode.insertBefore(container.firstChild, this);
    // And remove the node that has been replaced
    this.parentNode.removeChild(this);
}

// Now use these two functions as getters and setters for the 
// outerHTML property of all Element objects. Use ES5 Object.defineProperty
// if it exists and otherwise fall back on __defineGetter__ and Setter__.
if (Object.defineProperty) {
    Object.defineProperty(Element.prototype, "outerHTML", {
                              get: outerHTMLGetter,
                              set: outerHTMLSetter,
                              enumerable: false, configurable: true
                          });
}
else {
    Element.prototype.__defineGetter__("outerHTML", outerHTMLGetter);
    Element.prototype.__defineSetter__("outerHTML", outerHTMLSetter);
}
}());

Kudos: https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-15/implementing-the-outerhtml

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.