0

一些原生 javascript 对象的原型可以扩展为包含新函数(例如NodeList.prototype.forEachNodeList.prototype.addEventListener),我使用这些新函数来允许与NodeList. 到目前为止一切都很好,但是我应该如何将对象添加到原型中,而原型又具有自己的功能(允许NodeListVar.classList.remove("class"))。NodeListVar.classList().remove("class")通过执行以下操作,我已经能够做到

NodeList.prototype.classList = function(){
    var _this = this;
    return {
        remove: function(class){
            _this.forEach(function(){
                this.classList.remove(class);
            });
        }
    }   
};

但是,我非常希望语法与 normal 相同element,因此更像:

NodeList.prototype.classList = {
    remove: function(class){
        //where *this* would be the nodeList and *not* the DOMWindow
        this.forEach(function(){
            this.classList.remove(class);
        });
    }
};

这可能并不难,但我已经无休止地搜索了谷歌并且已经查看了无数问题并且找不到任何有用的东西。

4

2 回答 2

2

首先阅读:扩展 DOM 有什么问题

您不能在原型上设置对象。所有被调用的函数都将在该静态原型对象的上下文中执行,而不是 NodeList 本身。原型上的对象没有对当前 NodeList 的引用。

在 normal Elements 上,每个元素都有自己的classList属性,DOMTokenList绑定元素。你需要做同样的事情:给每个 NodeList 自己的 classLists 实例。由于您不能在不可用的构造函数中执行此操作,因此您必须使用 getter,如前所述。

我认为您不应该尝试在 NodeLists 上允许与 Elements 上相同的语法,因为它们非常不同。但是如果你想摆脱这些括号,你可以安装一个原生的 getter 函数

function ClassLists(nl) {
    ... // nl references the NodeList we're bound to
}
ClassLists.prototype = ...;

Object.defineProperty(NodeList.prototype, "classLists", {
    get: function() {
        return this.classLists = new ClassLists(this);
    }
});
于 2012-06-05T12:37:10.503 回答
0

只是为了补充@Bergi 的答案,这是一个跨浏览器的解决方案:

function ClassList() {
    this.nodeList;
}

ClassList.prototype = {
    constructor: ClassList,

    remove: function() {
        console.log( this );
    }
};

NodeList.prototype.classList = new ClassList();

nl.classList.remove(); // ClassList object with the `nodeList` property.

它不能与相同的 API 一起使用,因为它不是 using defineProperty,但它是跨浏览器的。defineProperty仅在 IE9 中可用,在 IE7 中不可填充。

于 2012-06-05T12:48:24.053 回答