JavaScript插件创建

JavaScript插件创建,javascript,plugins,Javascript,Plugins,如何创建一个纯JavaScript(不使用任何库)插件,该插件如下所示: document.getElementById('id').myPlugin(); 像jQuery?为什么要使用这种格式?我想 myPlugin(document.getElementById('id')) 对任何维护代码的人来说都可能更清楚。我不太喜欢。我同意。您真的不应该乱用标准JavaScript元素。最好为它做一个包装(即jQuery使用的$)。如果您想简化获取元素的方法,可以使用包装器方法并扩展该方法。这将使

如何创建一个纯JavaScript(不使用任何库)插件,该插件如下所示:

document.getElementById('id').myPlugin();

像jQuery?

为什么要使用这种格式?我想

myPlugin(document.getElementById('id'))
对任何维护代码的人来说都可能更清楚。我不太喜欢。我同意。您真的不应该乱用标准JavaScript元素。最好为它做一个包装(即jQuery使用的
$
)。如果您想简化获取元素的方法,可以使用包装器方法并扩展该方法。这将使代码更易于维护。因为如果修改JavaScript中的标准功能,可能会干扰标准行为。这可能会导致一些非常困难的调试。最好制作一个包装器函数,用它做任何你喜欢的事情

但是,尽管如此,如果您想搞乱标准行为,您始终可以使用原型将新方法绑定到标准对象。例如:

Object.prototype.myMethod = function () {}

我不敢说你不能。毕竟,Prototype.js做到了

要能够调用
getElementById('id')。someNewMethod()
您必须“扩展”对象类型的原型
getElementById
返回,它是一个
元素。在某些浏览器中,您确实可以做到这一点:

Element.prototype.someNewMethod= function() {
    alert('hello from a '+this.tagName);
};

document.body.someNewMethod(); // hello from a BODY
然而,这是相当值得怀疑的。在本机JavaScript对象(如
对象
字符串
上进行原型设计可能不够可靠,浏览器和库之间存在名称冲突,但是
元素
和所有其他DOM对象可能是“主机”对象,不允许进行原型设计

即使DOM对象是用完整的本机JavaScript接口实现的,也没有任何规范规定
元素
必须在名为
元素
窗口
属性/全局变量下公开原型/构造函数

事实上,这在Firefox、Webkit和Opera以及IE(从第8版开始)中确实有效。然而,它是不标准的,不是所有浏览器都以相同的名称提供所有相同的界面,而且它在IE6、IE7或许多较小的浏览器(例如移动浏览器)中也不起作用

Prototype为这些浏览器提供了一个退路:当它第一次看到每个元素时,它会尝试用新成员来扩充
元素的每个实例。但这有着极其混乱的副作用,许多人认为这是一个错误;再也没有了


也许将来有人会将其捆绑起来,使其成为浏览器环境中可靠的一部分。但今天情况并非如此,因此您应该继续使用其他更笨重的方法,如包装函数。

您可以创建自己的包装(类似于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(document.getElementById('id')).myPlugin();

值得注意的是,您所建议的语法与jquery完全不同,并且有很好的理由,fredrik已经详细阐述了一些很好的答案。但出于好奇,难道人们不应该用一些真正的狡猾的javascript代码来伪造它吗。首先保存原始的getElements并覆盖它?真正可怕的解决方案,但应该有效。:)是的,您可以:您基本上是在自己的重新实现中包装整个DOM。问题是(a)速度太慢,(b)许多DOM依赖于属性而不是方法:例如
document.body.firstChild
根本不进行方法调用。在ECMAScript第五版之前,您无法在JavaScript中定义自己的属性getter/setter,因此您无法拥有跨浏览器工作的动态属性,甚至无法很好地模拟节点列表/数组的属性。因此,您必须填写所有链接的
firstChild
​s和
nextSibling
​s和
parentNode
​在启动时和每次文档修改(eek!)时,或必须更改接口,例如,要求用户编写
document.getBody().getFirstChild()
。但是,如果您要更改接口,那么您就失去了本机DOM的优势,因此您最好只设计自己的接口(如jQuery等)。我不认为从这开始是个好主意。:)但是反应很好。现在棘手的部分是,如何编写一个比本机更快的DOM重新实现!
myWrapper(document.getElementById('id')).myPlugin();