how do I extend a javascript object such that in browsers that don't natively have outerHTML, I can define it?

StackOverflow https://stackoverflow.com/questions/8479880

Question

I found this function (though, I forget where):

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);
}

but this function works by calling outerHTML(my_element) rather than my_element.outerHTML

I want to be able to extend a javascript DOM element object such that it has the outerHTML element, but still use the native one if it exists. how do I do that?

The main reason why I want to do it this way is because Firefox doesn't natively have an outerHTML method, but I still want to use the native implementations if available, as they have been throughly tested, and I feel I can trust them.

UPDATE: @Raynos suggested that I not do the above for outerHTML, and taht I should do something a like the outerHTML specifications. I found this: How do I do OuterHTML in firefox? and it doesn't do .cloneNode, which can cause errors in FireFox 8.0.1.
So, my solution is this, as per @Raynos:

if (!("outerHTML" in HTMLElement.prototype)) {
    Object.defineProperty(HTMLElement.prototype, "outerHTML", {
        get: getOuterHTML
    });
}


function getOuterHTML(){
    var parent = this.parentNode;
    var el = document.createElement(parent.tagName);
    el.appendChild(this.cloneNode(true));
    var shtml = el.innerHTML;
    return shtml;
}
Was it helpful?

Solution

You generally do something like :

if (!("outerHTML" in document.body)) {
    Object.defineProperty(Element.prototype, "outerHTML", {
        get: getOuterHTML,
        set: setOuterHTML
    });
}

You then read the outerHTML specification and write getOuterHTML and setOuterHTML functions that implement it.

Note: I aggressively recommend against naively implementing an outerHTML property that's not spec compliant. This is going to cause you problems in maintenance when your "version" works differently from the native version. Especially if you add propietory extensions or extra "features" to your version

Note that Object.defineProperty is undefined in older browsers. You may need to use the shim from es5-shim

OTHER TIPS

Add it to the HTMLElement prototype

HTMLElement.prototype.outerHTML =  function() {
      // Your implementation of getting outerHTML
}

You might want to try extending the Node base object, from which almost all of the DOM extends, read here for a description Element element - MDN or as others responded try the HTMLElement read here also from MDN - HTMLElement

Element.prototype.outerHTML = function(){ console.log('hola'); };
HTMLElement.prototype.outerHTML = function(){ console.log('hola'); };

as Raynos on the comments pointed out here is the Spec article, which is encouraging to use Element.

Edit: Removed Node references

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top