DerpyNerd
DerpyNerd

Reputation: 4803

Extending HTMLElement interface with classes

I would like to extend the HTMLElement interface with a custom object on a custom property. Is that even possible?

This is what I've got:

if (typeof HTMLElement.prototype.classList === "undefined") {
    HTMLElement.prototype.classList = function ClassList() { return this.className.split(' '); };
    HTMLElement.classList.prototype.add = function(name) {
        if (classList.indexOf(name) !== -1) {
            return;
        }
        classList[classList.length] = name;
        this.className = classList.join(' ');
    };
    HTMLElement.classList.prototype.remove = function(name) {
        var index = classList.indexOf(name);
        if (index !== -1) {
            this.className = classList.splice(index + 1, 1).join(' ');
        }
    }
}

This should give you a good idea about what I need.

I want to implement my own classList functionality for IE9. In IE, this would result in undefined and would throw an error.

element.classList.add('fadeIn');

Is there a simple way to implement this?

EDIT

I've been toying around with this for a while but my knowledge isn't good enough yet to understand exactly what's going on. I still have to call document.getElementById('whatever').classList() to avoid getting "undefined". I would love to be able to call classList without braces (if the browser doesn't support classList, of course)

Upvotes: 1

Views: 1104

Answers (2)

GOTO 0
GOTO 0

Reputation: 47682

To define a getter (a function that can be invoked without parentheses), use Object.defineProperty. Works in IE9.

function getClassList()
{
    var element = this;
    var classList = this.className.split(' ');
    classList.add = function(name) {
        if (classList.indexOf(name) !== -1) {
            return;
        }
        classList.push(name);
        element.className = classList.join(' ');
    };
    classList.remove = function(name) {
        var index = classList.indexOf(name);
        if (index !== -1) {
            classList.splice(index, 1);
            element.className = classList.join(' ');
        }
    };
    return classList;
}

Object.defineProperty(HTMLElement.prototype, 'classList', { get: getClassList });

Upvotes: 1

alex
alex

Reputation: 490283

I think you've setup the prototype wrong.

You should be assigning classList to HTMLElement.prototype, not directly on HTMLElement itself.

To access it like it works natively, you could set it up like so...

HTMLElement.prototype.classList = function()
  // ...
};

HTMLElement.prototype.classList.add = function()
  // ...
};

HTMLElement.prototype.classList.remove = function()
  // ...
};

Upvotes: 1

Related Questions