Daniel Robinson
Daniel Robinson

Reputation: 14848

wrapping document.createElement() with custom type

I want to make a viewport type that basically wraps a <div> tag with some custom styling options, but I'm not sure how to add the elements methods to my viewport type, I am trying something like this:

var viewport = function(){
    document.createElement.call(this, 'div');
    // additional custom properties...
    this.customStuff = ExtraProperty;
}

//would this work?
viewport.prototype = Object.create(document.createElement.prototype);

// additional custom methods...
viewport.prototype.constructor = viewport;

I want my viewport objects to be able to be used just like a Element object. So I could call like this:

var myVP = new viewport();
myVP.appendChild(someotherElementType);

I'm just not sure how to wrap document.createElement properly/effectively as I'm not sure where the .appendChild and other methods live etc. If it were used like a typical constructor I know I could use the pattern above but as you don't need to write new document.createElement('type'); I'm not sure.

Thanks.

Upvotes: 0

Views: 1505

Answers (1)

Rob W
Rob W

Reputation: 348982

  1. document.createElement should always be executed in the context of a document. Using .call or .apply does not make sense here.
  2. Elements created using document.createElement do not inherit from document.createElement.prototype (it's not even a constructor!). DOM elements are implementing interfaces. When a method/property is both defined on Node and Element, then the one from Element takes precedence. In general, this should be the order of "inheritance":
    Node > Element > HTMLElement > HTMLNameElement.

When you want to add a custom property, extend one of these prototypes, e.g.

Node.prototype.foo = 1;
console.log(document.createElement('div').foo); //"1"

But these cannot be used as a constructor:

new HTMLDivElement; // TypeError: HTMLDivElement.prototype is not a constructor
Object.create(HTMLLIElement).innerHTML; // undefined
Object.create(HTMLAnchorElement).href ; // undefined

But you cannot create custom elements by defining a global HTMLNameElement object:

window.HTMLHelloElement = HTMLDivElement; // Expected: Create alias for div
document.createElement('hello');          // Result: [object HTMLUnknownElement]

Compatibility:

  • IE 7- does not expose any inheritable prototype
  • IE8: Elements only inherit from Element.prototype.
  • IE9+ / Chrome 1+ / Firefox 1+ / Opera 8+ / Safari 3+: Follows the standard.

"I want to make a viewport type that basically wraps a tag with some custom styling options"

Class names and CSS are more suitable for defining class-specific styles. For example:

var foo = document.createElement('div');
foo.className = 'type-viewport';       // CSS style sheet: .type-viewport { ... }

Upvotes: 1

Related Questions