最近在看jquery插件开发,google找了很多教程看,现在总结一下,主要是对知识的一个总结和记录,很多都是参考别人的教程的,最后会贴参考链接。
最后的jquery插件模板:
(function($){
    $.fn.插件名 = function(settings){
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend({},$.fn.插件名.defaultSettings,settings);
        return this.each(function(){
              debug(this);
              // 引用回调函数,引用位置自己把握
              if (typeof settings.initFn == 'function') { // 确保类型为函数类型
                  settings.initFn.call(this); // 执行回调函数
              }
        });
    }
    // 私有函数:debugging
    function debug($obj) {
        if (window.console && window.console.log)
        window.console.log('hilight selection count: ' + $obj.size());
    };
    // 插件的defaultSettings
    var defaultSettings = {
        initFn : null //当插件初始化完成后执行的回调函数, 默认为null
    }
})(jQuery)
现在从头开始,先上jquery插件的基础模板:
(function($){
    $.fn.插件名 = function(settings){
        var defaultSettings = {
        }
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend({},defaultSettings,settings);
        return this.each(function(){
        });
    }
})(jQuery)
现在我们来分析这段模板代码:
一、首先看第一句:
(function($){
})(jQuery);
这段代码是为了创建一个匿名函数,[JavaScript中的匿名函数及函数的闭包](http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html)这篇文章详细介绍了匿名函数和闭包,可以仔细看下。匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。
_1、模板中匿名函数的作用_
保护“$”这个变量,避免“$”这个变量与你页面中的全局变量冲突。
这点非常重要,“$”这个变量在编程语言中使用率非常高,你无法保证你所引入的其他js都是用“$”来代表“jQuery”。
_2、$与jQuery_
jQuery是jquery库定义的一个全局变量,而$这个变量相当于jQuery的简写,$的冲突率是非常高的,不同的js框架$有不同的含义,但如果都使用jQuery,那是非常繁琐的一件事,这就是
(function($){
})(jQuery);
这行代码的用处,这个匿名函数创建了闭包,意味着在这个闭包内,你可以任意的使用$这个变量,不用担心冲突的问题。
_3、匿名函数的函数体形式_
(function( x , y){
    alert( x + y);
})(2 ,3 );
你可以试运行下上面的代码,再对照下模板中的第一行代码,也许你就会大致明白其形式。
(function($){
});
定义一个带有个名为“$”参数的匿名函数。
(function($){
})(jQuery);
将jQuery这个全局变量传入匿名函数,并执行匿名函数。
**二、$.fn的含义**
(function($){
    $.fn.插件名= function(settings){
    }
});
$.fn或者jQuery.fn本质上可以等于jQuery.prototype。
**三、jquery的继承方法$.extend**
(function($){
    $.fn.插件名= function(settings){
                //默认参数
        var defaultSettings = {
        }
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend(defaultSettings,settings);
    }
})(jQuery);
$.extend在jquery插件开发中有个很重要的作用,就是用于合并参数。
举个例子:
(function($){
    $.fn.colorTip= function(settings){
        var defaultSettings = {
            //颜色
            color        : 'yellow',
            //延迟
            timeout        : 500
        }
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend(defaultSettings,settings);
               alert(settings.color);
    }
});
//插件调用
$('a').colorTip({color:'blue'});
如果你运行以上代码,就会发现弹出的值为blue,而不再是默认的yellow。
$.extend(defaultSettings,settings);的含义是,使用settings来覆盖defaultSettings(同名键值)。
实际上.extend不止接受二个参数,相对于模板上的写法,还有下面的写法:
settings = $.extend({},defaultSettings,settings);
即不去覆盖defaultSettings(默认参数),而是合并到一个空的Object。
推荐阅读:[jQuery.extend 函数详解](http://www.cnblogs.com/RascallySnake/archive/2010/05/07/1729563.html),这篇文章讲解的非常到位。
**三、this**
其中的 this 关键字,指向的是调用这个插件的 jQuery 对象。
一个典型的 jQuery 对象通常包含许多 DOM 元素,所以说 jQuery 对象也被看做是 DOM 对象集。因此,如果要对对象集中的每个元素作处理,就要借助于 jQuery 的 each() 方法:
return this.each(function(){
});
附上Colortip的代码
(function($){
    $.fn.colorTip = function(settings){
        var defaultSettings = {
            //颜色
            color        : 'yellow',
            //延迟
            timeout        : 500
        }
        //提示框的颜色
        var supportedColors = ['red','green','blue','white','yellow','black'];
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend(true,defaultSettings,settings);
        return this.each(function(){
            var elem = $(this);
            // 如果该对象不包含title属性,直接予以返回
            if(!elem.attr('title')) return true;
            // 实例化eventScheduler(定时器)
            var scheduleEvent = new eventScheduler();
            //实例化Tip(提示类,产生、显示、隐藏)
            var tip = new Tip(elem.attr('title'));
            // 产生提示框,并给提示框父容器添加样式
            elem.append(tip.generate()).addClass('colorTipContainer');
            // 检查提示框父容器是否有颜色样式
            var hasClass = false;
            for(var i=0;i<supportedColors.length;i++)
            {
                if(elem.hasClass(supportedColors[i])){
                    hasClass = true;
                    break;
                }
            }
            // 如果没有,使用默认的颜色
            if(!hasClass){
                elem.addClass(settings.color);
            }
            // 鼠标滑过提示框父容器时,显示提示框
            // 鼠标移出,则隐藏
            elem.hover(function(){
                tip.show();
                //清理定时器
                scheduleEvent.clear();
            },function(){
                //启动定时器
                scheduleEvent.set(function(){
                    tip.hide();
                },settings.timeout);
            });
            //删除title属性
            elem.removeAttr('title');
        });
    }
    /*
    /    定时器类
    /    这里需要你具备javascript面向对象编程方面的一些知识。
    /    eventScheduler类很简单,只有二个方法,set():添加定时器,clear ():清理定时器
    */
    function eventScheduler(){}
    eventScheduler.prototype = {
        set    : function (func,timeout){
            //添加定时器
            this.timer = setTimeout(func,timeout);
        },
        clear: function(){
            //清理定时器
            clearTimeout(this.timer);
        }
    }
    /*
    /    提示类
    /    Tip也是个javascript类,具有三个方法:generate、show、hide。
    /    值得一提的是,Tip和eventScheduler类是在$.fn.colorTip函数体外。
    */
    function Tip(txt){
        this.content = txt;
        this.shown = false;
    }
    Tip.prototype = {
        generate: function(){
            //产生提示框
            return this.tip || (this.tip = $(''+this.content+
                                             ''));
        },
        show: function(){
            //显示提示框
            if(this.shown) return;
            this.tip.css('margin-left',-this.tip.outerWidth()/2).fadeIn('fast');
            this.shown = true;
        },
        hide: function(){
            //隐藏提示框
            this.tip.fadeOut();
            this.shown = false;
        }
    }
})(jQuery);
补充优化:
1、Colortip的代码有个定时器类和提示类,这个可以看做是插件的私有函数,这样我们可以定义更多的函数而不搅乱命名空间也不暴露实现,这就是闭包的功能。代码示例:
(function($){
    $.fn.插件名 = function(settings){
        debug(this);
    }
    // 私有函数:debugging
    function debug($obj) {
        if (window.console && window.console.log)
        window.console.log('hilight selection count: ' + $obj.size());
    };
})(jQuery)
2、暴露插件的默认设置
我们应该对上面代码的一种改进是暴露插件的默认设置。这对于让插件的使用者更容易用较少的代码覆盖和修改插件。接下来我们开始利用函数对象。
(function($){
    $.fn.插件名 = function(settings){
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend({},$.fn.插件名.defaultSettings,settings);
        return this.each(function(){
        });
    }
    // 插件的defaultSettings
    var defaultSettings = {
    }
})(jQuery)
如果再结合上篇的jquery插件回调函数,可以修改jquery模板代码:
(function($){
    $.fn.插件名 = function(settings){
        /* 合并默认参数和用户自定义参数 */
        settings = $.extend({},$.fn.插件名.defaultSettings,settings);
        return this.each(function(){
              debug(this);
              // 引用回调函数,引用位置自己把握
              if (typeof settings.initFn == 'function') { // 确保类型为函数类型
                  settings.initFn.call(this); // 执行回调函数
              }
        });
    }
    // 私有函数:debugging
    function debug($obj) {
        if (window.console && window.console.log)
        window.console.log('hilight selection count: ' + $obj.size());
    };
    // 插件的defaultSettings
    var defaultSettings = {
        initFn : null //当插件初始化完成后执行的回调函数, 默认为null
    }
})(jQuery)
自己写的一个简单例子:
(function($){
$.fn.arayzou = function(settings){
    /* 合并默认参数和用户自定义参数 */
    settings = $.extend({},$.fn.arayzou.defaultSettings,settings);
    return this.each(function(){
        console.log('执行插件');
        var $this = $(this);
        $this.hover(function(){
            debug();
        })
        $this.click(function(){
            // 引用回调函数
            if (typeof settings.initFn == 'function') { // 确保类型为函数类型
                settings.initFn.call(this); // 执行回调函数
            }
        })
    });
}
// 私有函数:debugging
function debug() {
    console.log('私有函数');
};
// 插件的defaultSettings
var defaultSettings = {
    initFn : null //当插件初始化完成后执行的回调函数, 默认为null
}
})(jQuery)
调用:
demo地址:jqueryPlug.html
文章参考:
制作jquery文字提示插件—jquery插件实战教程
jQuery插件开发全解析
A Plugin Development Pattern