Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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;
}
like image 340
NullVoxPopuli Avatar asked Jan 18 '23 01:01

NullVoxPopuli


1 Answers

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

like image 168
Raynos Avatar answered Jan 25 '23 12:01

Raynos