如何编写jQuery插件

1. jQuery插件的介绍

首先,得明白编写插件的目的:给已经有的一系列方法或函数做一个封装,以便在其他地方重复使用,方便后期维护和提高开发效率。接下来,你就需要知道jQuery插件的分类:

  • 封装对象方法的插件:将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,在jQuery内库中许多方法都是通过这种方式的,如parent()方法,appendTo()方法,用到的就是jQuery.fn[ name ] = function(){ ……}
  • 封装全局函数的插件:将独立的函数加到jQuery命名空间之下,常用的jQuery.ajax()以及jQuery.trim()方法等
  • 选择器插件:个别情况下,例如想要扩展一个自己喜欢的选择器

2. 需要注意的问题

  • 所有的对象方法都应该附加在jQuery.fn对象上,而所有的全局函数都应该附加到jQuery对象本身上
  • 在插件内部,this指向的是当前通过选择器获取的jQuery对象
  • this.each可以遍历元素

3. 通过闭包写插件

自执行的函数形式,在前面加“:”的原因是为了更好的兼容性,利用闭包可以避免临时变量影响全局变量,可以在插件内部使用$作为别名来代替jQuery,当然下面的形式只是一种常见的形式

:(function() {
    //编写jQuery插件代码
})(jQuery);

4. jQuery本身对于扩展的支持

jQuery提供了两个用于扩展jQuery功能的方法,即jQuery.fn.extend()方法和jQuery.extend()方法,前者用于扩展之前提到的第一种插件,后者用于扩展后面的两种

介绍一下jQuery.extend()方法,该方法除了可以用于扩展jQuery对象之外,还有很强大的功能,就是扩展已有的Object对象,这在后面的例子中也有用到

5. 实现一个轮播图插件

先看一下实现的效果:

jquery 插件写法教程 jquery 插件编写_插件

页面结构如下:

实现图片滚动的原理(参考:),由此也可以清晰的看到在这里我编写的插件就是 carousel.js

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript" src="carousel.js"></script>  
</head>
<body>
    <div class="carousel">
        <div class="Con">
        <!-- 轮播(carousel)项目 -->
            <div class="scroll">
                <img src="./pic/1.jpg">
                <img src="./pic/2.jpg">
                <img src="./pic/3.jpg">
                <img src="./pic/4.jpg">
                <img src="./pic/5.jpg">
                <img src="./pic/6.jpg">
                <img src="./pic/7.jpg">             
            </div>

            <!-- 轮播(carousel)指标 -->
            <ol class="But">
                <li class="active"></li>  <!-- 0 * img.width -->
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ol>
        </div>

        <!-- 轮播(carousel)导航 -->
        <a href="javascript:void(0)" class="prev" data-slide="prev"><<</a>
        <a href="javascript:void(0)" class="next" data-slide="next">>></a>
    </div>

    <script type="text/javascript">
        $(".carousel").carousel({
/*          Automatic : false,*/
            Data : 500  
        });
    </script>
</body>
</html>

carousel.js 如下所示:

(function(global, factory, plug) {
    factory(global.jQuery, plug);
})(window, function($, plug) {
    var _DEFAULTS_ = {
        Automatic : true,
        Data : 2000,
        initEvent : 'click'
    };

    $.fn[plug] = function(options) {  //在jQuery的原型之上扩展的方法  $.fn[plug]
        //得到所有的li
        //console.log(this);   此处的this是一个jQuery对象,谁调用plug方法,这个this就指向的是谁
        var $dots = $(this).find("ol").find("li");
        var num = $dots.length - 1;
        var _this = $(this);
        var $width = _this.width();
        var time = 0;
        var $index = 0;

        $.extend(this, _DEFAULTS_, options);
        //extend给当前的对象扩展属性(原来的要,扩展的也要)    以默认为优先  以用户配置为覆盖
        if(this.Automatic) {
            play();
        }

        $dots.on(this.initEvent, function() {
            //停止定时器
            clearInterval(time);
            $but = $(this);
            $index = $but.index();    //前面的Img数目

            $but.addClass('active').siblings('li').removeClass('active');
            $('.scroll').animate({left: -$index*$width}, _this.Data);

            //开启定时器
            play();
        });
        $('.prev').click(function() {
            controlPreAndNext(false);
        });
        $('.next').click(function() {
            controlPreAndNext(true);
        });

        function controlPreAndNext(isNext) {
            clearInterval(time);

            switch(isNext) {
                case false : 
                    $index--;
                    $index = $index < 0 ? num : $index;
                    break;
                case true : 
                    $index++;
                    $index = $index > num ? 0 : $index;
                    break;
                default :
                    break;
            }

            if($index < 0) {
                $index = num;
            }
            $('.scroll').animate({left: -$index*$width}, _this.Data);
            $dots.eq($index).addClass('active').siblings('li').removeClass('active');
            play();
        }

        function play() {
            time = setInterval(function() {
                $index++;
                if($index > num) {
                    $('.scroll').css("left", 0);
                    $index = 0;
                }
                $('.scroll').animate({left : -$index*$width}, _this.Data);
                $dots.eq($index).addClass('active').siblings('li').removeClass('active');
            }, 4000);
        }
    };
}, "carousel");

在该示例中,我采用的封装的方法是:

(function(root, fun, options) {
    fun(root, options);
})(window, function() {

    //……插件代码

}, "name");    //这里可以不写window,而写成window.jQuery

在其中使用到$.extend(),也正是向我注释中写的那样,extend给当前的对象扩展属性(原来的要,扩展的也要),关于默认的和配置的,秉持“以默认为优先 以用户配置为覆盖”的原则