最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript plugin creation - Stack Overflow

programmeradmin1浏览0评论

How to create a pure JavaScript (without using any library) plugin which looks like:

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

Like jQuery?

How to create a pure JavaScript (without using any library) plugin which looks like:

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

Like jQuery?

Share Improve this question edited Nov 29, 2010 at 21:16 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Apr 26, 2010 at 8:50 AneeshAneesh 1,2033 gold badges17 silver badges26 bronze badges 1
  • 1 it's worth noting that the syntax you've suggested is not at all like jquery and for very good reasons, some of which fredrik has elaborated on – David Hedlund Commented Apr 26, 2010 at 9:06
Add a comment  | 

4 Answers 4

Reset to default 8

You can create your own wrapper (similar to jQuery), and doing this will allow you to circumvent all of the discussed problems with extending the DOM directly.

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;

})();

And you can add your own methods like so:

myWrapper.NodeList.prototype.myPlugin = function() {
    return this.each(function(){
        // Do something with 'this' (the element)
    });
};

Usage:

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

I hesitate to say you can't. After all, Prototype.js did.

To be able to call getElementById('id').someNewMethod() you would have to ‘extend’ the prototype of the type of object getElementById returns, which is an Element. In some browsers you can indeed do that:

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

document.body.someNewMethod(); // hello from a BODY

However, this is quite questionable. Prototyping onto the native JavaScript objects like Object or String is potentially dodgy enough, what with name clashes between browsers and libraries, but Element and all the other DOM objects may be ‘host’ objects, which don't permit prototyping.

Even if DOM objects are implemented with a full native JavaScript interface, no specification says that Element must expose a prototype/constructor-function under a window property/global variable called Element.

In reality this does work in Firefox, Webkit and Opera, and IE from version 8 onwards. However it's unstandardised, not all browsers make all the same interfaces available under all the same names, and it won't work in IE6, IE7 or many smaller browsers (eg. mobile browsers).

Prototype had a fallback for these browsers: it would try to augment every instance of an Element with the new members when it first saw each element. But this had extremely messy side-effects and is considered by many to be a mistake; Prototype 2.0 won't try to extend DOM interfaces any more.

Maybe in the future somebody will tie this down and make it a reliable part of the browser environment. But today that's not the case, so you should continue to use other, clunkier methods such as wrapper functions.

Why use that format? I think

myPlugin(document.getElementById('id'))

would probably be clearer to anyone maintaining the code. I'm not a big fan of monkey patching.

I agree with spender. You should really not mess around with standard JavaScript elements. It's better to do a wrapper for it (that is, $ as jQuery uses). If you want to make a shorthand for getting elements do a wrapper method and extend that one instead. This will make the code easier to maintain. Since if you modify the standard functionality in JavaScript it may interfere with the standard behavior. This could lead to some really hard debugging. It's better to make a wrapper function, do whatever you like with it.

But despite of this, if you want to mess around with the standard behavior, you can always bind new methods to the standard objects using prototyping. For example:

Object.prototype.myMethod = function () {}
发布评论

评论列表(0)

  1. 暂无评论