如何创建纯JavaScript(不使用任何库)插件,如下所示:
document.getElementById('id').myPlugin();
和jQuery一样?
答案 0 :(得分:4)
您可以创建自己的包装器(类似于jQuery),这样做可以避免直接扩展DOM所有讨论的问题。
myWrapper = (function(){
function NodeList(elems) {
this.length = 0;
this.merge(this, elems.nodeType ? [elems] : elems);
}
function myWrapper(elems) {
return new NodeList(elems);
}
myWrapper.NodeList = NodeList;
NodeList.prototype = {
merge: function(first, second) {
var i = first.length, j = 0;
for (var l = second.length; j < l; ++j) {
first[i++] = second[j];
}
first.length = i;
return first;
},
each: function(fn) {
for (var i = -1, l = this.length; ++i < l;) {
fn.call(this[i], this[i], i, l, this);
}
return this;
}
};
return myWrapper;
})();
你可以像这样添加自己的方法:
myWrapper.NodeList.prototype.myPlugin = function() {
return this.each(function(){
// Do something with 'this' (the element)
});
};
用法:
myWrapper(document.getElementById('id')).myPlugin();
答案 1 :(得分:3)
我犹豫说你做不到。毕竟,Prototype.js确实如此。
为了能够调用getElementById('id').someNewMethod()
,你必须'扩展'对象类型getElementById
返回的原型,这是一个Element
。在某些浏览器中,您确实可以这样做:
Element.prototype.someNewMethod= function() {
alert('hello from a '+this.tagName);
};
document.body.someNewMethod(); // hello from a BODY
然而,这是值得怀疑的。对Object
或String
等本机JavaScript对象进行原型设计可能很狡猾,浏览器和库之间存在名称冲突,但Element
和所有其他DOM对象可能是'主机'对象,不允许原型制作。
即使DOM对象是使用完整的本机JavaScript接口实现的,也没有规范说Element
必须在名为window
的{{1}}属性/全局变量下公开原型/构造函数。
实际上,这适用于Firefox,Webkit和Opera,以及从版本8开始的IE。然而,它并非标准化,并非所有浏览器都以相同的名称提供所有相同的接口,并且它在IE6,IE7或许多较小的浏览器(例如移动浏览器)中不起作用。
Prototype有这些浏览器的后备:它会在第一次看到每个元素时尝试用新成员扩充Element
的每个实例。但这有非常混乱的副作用,许多人认为这是一个错误; Prototype 2.0 won't try to extend DOM interfaces了。
将来可能会有人将其打成平手并使其成为浏览器环境的可靠部分。但是今天情况并非如此,所以你应该继续使用其他更笨重的方法,比如包装函数。
答案 2 :(得分:1)
我同意spender。你应该不要乱用标准的JavaScript元素。最好为它做一个包装器(即jQuery使用的$
)。如果你想简单地获取元素,请做一个包装器方法并扩展它。这将使代码更易于维护。因为如果您在JavaScript中修改标准功能,它可能会干扰标准行为。这可能会导致一些非常困难的调试。最好制作一个包装函数,用它做任何你喜欢的事情。
但是尽管如此,如果你想弄乱标准行为,你总是可以使用原型设计将新方法绑定到标准对象。例如:
Object.prototype.myMethod = function () {}
答案 3 :(得分:0)