In JavaScript, Can You Extend the Dom

In Javascript, can you extend the DOM?

you can extend the DOM by using the Element's prototype. However, this does not work in IE7 and earlier. You will need to extend the specific element, one at a time. The Prototype library does this. I recommend looking through the source to see exactly how it's done.

How to extend DOM Element as a Class (without jQuery)

In firefox, chrome and IE8+ elements inherit from Element.prototype so you must do:

Element.prototype.doSomething = function() {
alert("hello");
};

Extending host prototypes is very fragile and not recommended but should be fine if you are just playing around. The main reason is that DOM specification doesn't specify prototypal implementations but just interfaces, elem.appendChild() should just work, it doesn't have to be in some prototype.


This:

function $id(str) {
this.element = document.getElementById(str);
return element;
}

Only worked because of the undesired behavior that this refers to the global object when a function is invoked without any object context (It should just flat out throw an error at the mere sight of this, though strict mode somewhat fixes this by setting it to undefined). You are making a global variable element (since property assignments to the global object become global variables) and then returning the global variable.

How do I (and should I) make additional methods on DOM objects?

If you want to be able to call custom methods on an instance which alters a DOM element, it would probably make the most sense to have the class just save the DOM element as a property of the instance, and then look it up when necessary. For example:

class MyElement {
constructor(element) {
this.element = element;
}
triggerDisplay() {
const { element } = this;
if (element.style.display === 'none') element.style.display = null;
else element.style.display = 'none';
}
}

const myCustomElement = new MyElement(document.getElementById('myDiv'));

myCustomElement.triggerDisplay();

If you need to be able to directly reference element properties without going through the .element property, you can use prototypal inheritence to set the element as the internal prototype of the instance:

const customProps = {
triggerDisplay: {
value: function() {
const element = Object.getPrototypeOf(this);
if (element.style.display === 'none') element.style.display = null;
else element.style.display = 'none';
}
}
};
const makeCustomElement = (element) => {
return Object.create(element, customProps);
};

const myCustomElement = makeCustomElement(document.getElementById('myDiv'));

myCustomElement.triggerDisplay();

(if you also want to assign to properties directly on the myCustomElement, then use another Object.create wrapper so that assignment does not mutate the customProps object)

Extend Prototype of DOM element

To solve this problem, as said, you can wether extend the prototype of all Elements via:

Element.prototype.newMethod = function(){};

However, to add it to a single DOM element, you can do:

HTMLXyzElement.prototype.newMethod = function(){};

Where Xyz is your element, eg:

HTMLFormElement, HTMLImageElement, HTMLAnchorElement, HTMLDivElement.
To find more of these just open a console in your browser and start typing HTML...

How to extend native DOM elements using is?

looks like you forgot to tell your web component, that it extends the native img element. Here's a running example based on your fiddle but broken down to the important bits: http://jsbin.com/OMaPIVoV/7/edit

hope this helps!

Using object wrappers to extend the JavaScripts DOM?

Object wrappers are more expensive than extensions because you need to create a new object, but they are safer.

A simple implementation that wraps only a single element could look like this:

(function() {
window.wrap = function(el) {
return new Wrapper(el);
};

function Wrapper(el) {
this.element = el;
}

Wrapper.prototype.addClass = function(cls) {
if (this.element)
this.element.className += " " + cls;
}
Wrapper.prototype.swap = function(el) {
this.element = el;
}
})();

Then you could make a new wrapper, and to be more efficient, you could reuse it with various elements.

var wrp = wrap(document.body);

wrp.addClass("foo");
wrp.swap(document.body.firstElementChild);
wrp.addClass("bar");

Another feature you could implement would be to add return this; to all the wrapper methods. That way you could chain your function calls if you like.

var wrp = wrap(document.body);

wrp.addClass("foo")
.swap(document.body.firstElementChild)
.addClass("bar");

You could also implement your wrapper to hold multiple elements at numeric indices like an Array, or better, simply hold an Array of elements.



Related Topics



Leave a reply



Submit