jQuery扩展

* jQuery.fn.extend()与jQuery.extend()

jQuery.fn如何扩展。

jQuery插件 $.fn(object)与$.extend(object)

jQuery提供了两个方法帮助开发插件

  • $.extend(object);扩展jQuery类本身;
  • $.fn.extend(object);扩展jQuery对象;

1、扩展jQuery对象

$.fn 等于 $.prototype;这样就好理解了,就好比对String.porotype增加一个函数,然后所有的字符串对象都能够直接调用,jQuery也是如此,扩展原型方法,相当给对象添加“成员方法”,类的成员方法要对象才可以调用。给jQuery增加一个函数,然后所有的jQuery对象都能够调用。jQuery对象就是$("#id"),调用$("#id").modify();
写法:$.fn或$.fn.extend({})

//扩展jQuery对象;$.fn.extend({})
        $.fn.modify = function () {
            $(this).val('********').css('color', 'yellow');
        }
        $.fn.extend({
            clear: function () {
                $(this).val('');
            }
        });    //调用, $('input').clear(); 对象.成员方法

2、扩展jQuery类

2.1 $.extend()方法重载

  - $.extend(obj)一个参数用于扩展jQuery类本身,相当于jQuery类的静态方法,使用“类名.方法名()”调用。

$.extend其实就是扩展"jQuery"这个类本身的静态函数。

//扩展jQuery对象本身
jQuery.extend({
  "minValue": function (a, b) {
    return a < b ? a : b;
  },
  "maxValue": function (a, b) {
    return a > b ? a : b;
  }
});
//调用
var i = 100; j = 101;
var min_v = $.minValue(i, j); // min_v 等于 100
var max_v = $.maxValue(i, j); // max_v 等于 101

3、 $.extend([deep], target, object1, [objectN])

  - 用一个或多个对象来扩展一个对象,返回被扩展的对象;

  - 如果不指定target,则给$命名空间本身进行扩展,为插件新增方法;

  - deep: true。 可选,weitrue,则递归合并

  - target:待修改的对象

  - object1: 待合并到第一个对象的对象

  - objectN:  可选,待合并到一个对象的对象

示例1:
合并 settings 和 options,修改并返回 settings。
var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
结果:
settings == { validate: true, limit: 5, name: "bar" }

示例2:
合并 defaults 和 options, 不修改 defaults。
var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = jQuery.extend(empty, defaults, options);

结果:
settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }

4、 demo

var menu = (function (window, undefined) {
    var id = "tab_menu";
    var This;
    var $menu = $("#" + id);
    var Menu = function () {
        This = this;
        this.Init.apply(this, arguments);
    }
    Menu.prototype.BindMenu = function () {
        /*为选项卡绑定右键*/
        $(".tabs li").on('contextmenu', function (e) {
            /*选中当前触发事件的选项卡 */
            var subtitle = $(this).text();
            $('#mainTab').tabs('select', subtitle);
            //显示快捷菜单
            $('#tab_menu').menu('show', {
                left: e.pageX,
                top: e.pageY
            });
            return false;
        });
    };
    Menu.prototype.Init = function () {
        $menu.menu({
            onClick: function (item) {
                var currTab = tab.GetCurrTab();
                if (item.id === "tab_menu-tabrefresh") {
                    //刷新
                    tab.Refresh();
                } else if (item.id === "tab_menu-openFrame") {
                    //在新窗口打开该标签
                    window.open(currTab.ref);
                } else if (item.id === "tab_menu-openFrame2") {
                    //在新Tab打开该标签
                    tab.Add({ id: currTab.id, title: currTab.id, ref: currTab.ref.replace('/', '%') });
                } else if (item.id === "tab_menu-tabcloseall") {
                    //全部关闭
                    tab.RemoveAll();
                } else if (item.id === "tab_menu-tabcloseother") {
                    //关闭除当前之外的TAB
                    tab.RemoveOthers();
                } else if (item.id === "tab_menu-tabcloseleft") {
                    //关闭当前左侧的TAB
                    var prevall = $('.tabs-selected').prevAll();
                    if (prevall.length === 0) {
                        return false;
                    }
                    prevall.each(function (i, n) {
                        if ($('a.tabs-close', $(n)).length > 0) {
                            //var t = $('a:eq(0) span', $(n)).text();
                            var t = $(n).index();
                            $('#mainTab').tabs('close', t);
                        }
                    });
                    return false;
                } else if (item.id === "tab_menu-tabcloseright") {
                    //关闭当前右侧的TAB
                    var nextall = $('.tabs-selected').nextAll();
                    if (nextall.length === 0) {
                        return false;
                    }
                    nextall.each(function (i, n) {
                        if ($('a.tabs-close', $(n)).length > 0) {
                            var t = $(n).index();
                            //  var t = $('a:eq(0) span', $(n)).text();
                            $('#mainTab').tabs('close', t);
                        }
                    });
                    return false;
                } else if (item.id === "tab_menu-tabclose") {
                    //关闭当前
                    tab.Remove(currTab.id);
                }
            }
        });
    };

    return new Menu();
})(window);
菜单的扩展

调用:

 //右击菜单绑定
    menu.BindMenu();

5、简单应用

1、$.extend(object)

  类似于.Net的扩展方法,用于扩展jQuery。然后就可以用$.的方式调用。

    $(function(){
        $.extend({ fun1: function () { alert("为jQuery扩展一个fun1函数!"); } });
        $.fun1();
    })

2、$.fn.extend(object)

  扩展jQuery的对象。

    $.fn.extend({ fun2: function () { alert("执行方法2"); } });
    $("#id1").fun2();

  可以用google来看看:

  

  上面的写法等同于:

    $.fn.fun2 = function () { alert("执行方法2"); }
    $(this).fun2();

3、私有域

  其定义方式如下:

(function ($) { })(jQuery);
//相当于
var fn = function (xxoo) { };
fn(jQuery);

  以下代码弹出123。

  $(function(){
     var fn = function (xxoo) { };
     fn(alert(123));
  })

* 插件开发

1、定义作用域

  开发一个jQuery插件,首先要把插件的代码与外界隔离开来,外部的代码不允许直接访问插件内部的代码,插件内部的代码也不影响外部。

    //步骤1 定义插件私有作用域
    (function ($) {

    })(jQuery);

  这样就能保证插件内部的代码与外界隔离了。

2、扩展jQuery

  定义了作用域之后,为了能够让外部调用,就需要将插件扩展到jQuery。

复制代码
    //步骤1 定义私有作用域
    (function ($) {
        //步骤2 插件的扩展方法名称
        $.fn.MyFrame = function (options) {
            
        }
    })(jQuery);
复制代码

3、默认值

  定义了jQuery插件之后,如果希望某些参数具有默认值,那么可以以这种方式来指定。

复制代码
    //步骤1 定义私有作用域
    (function ($) {
        //步骤3 插件的默认值属性
        var defaults = {
            Id: '#id1',
        };
        //步骤2 插件的扩展方法名称
        $.fn.MyFrame = function (options) {
            //步骤3 合并用户自定义属性,默认属性(如果options为空,则使用defaults)
            var options = $.extend(defaults, options);
        }
    })(jQuery);
复制代码

4、支持jQuery选择器

复制代码
    //步骤1 定义私有作用域
    (function ($) {
        //步骤3 插件的默认值属性
        var defaults = {
            Id: '#id1',
        };
        //步骤2 插件的扩展方法名称
        $.fn.MyFrame = function (options) {
            //步骤3 合并用户自定义属性,默认属性(如果options为空,则使用defaults)
            var options = $.extend(defaults, options);
        }
        //步骤4 支持jQuery选择器
        this.each(function () {

        });
    })(jQuery);
复制代码

5、支持jQuery的链式调用

复制代码
    //步骤1 定义私有作用域
    (function ($) {
        //步骤3 插件的默认值属性
        var defaults = {
            Id: '#id1',
        };
        //步骤2 插件的扩展方法名称
        $.fn.MyFrame = function (options) {
            //步骤3 合并用户自定义属性,默认属性(如果options为空,则使用defaults)
            var options = $.extend(defaults, options);
        }
        //步骤4 支持jQuery选择器
        //步骤5 支持链式调用(将步骤4返回)
        return this.each(function () {

        });
    })(jQuery);
复制代码

6、插件内部方法  

复制代码
    //步骤1 定义私有作用域
    (function ($) {
        //步骤3 插件的默认值属性
        var defaults = {
            Id: '#id1',
        };

        //步骤6 在插件里定义函数
        var MyFun = function (obj) {
            alert(obj);
        }

        //步骤2 插件的扩展方法名称
        $.fn.MyFrame = function (options) {
            //步骤3 合并用户自定义属性,默认属性(如果options为空,则使用defaults)
            var options = $.extend(defaults, options);
        }
        //步骤4 支持jQuery选择器
        //步骤5 支持链式调用(将步骤4返回)
        return this.each(function () {
            //步骤6 在插件里定义函数
            MyFun(this);
        });
    })(jQuery);
复制代码

  由于作用域关系,步骤6的私有函数目前允许的插件内部使用。

  本文乃笔记,原文来自:http://www.cnblogs.com/xcj26/p/3345556.html

* 自执行的匿名函数闭包

1. 什么是自执行的匿名函数?

它是指形如这样的函数: (function {// code})();

2. 疑问 为什么(function {// code})();可以被执行, 而function {// code}();却会报错?

3. 分析

(1). 首先, 要清楚两者的区别:

(function {// code})是表达式, function {// code}是函数声明.

(2). 其次, js"预编译"的特点:

js在"预编译"阶段, 会解释函数声明, 但却会忽略表式.

(3). 当js执行到function() {//code}();时, 由于function() {//code}在"预编译"阶段已经被解释过, js会跳过function(){//code}, 试图去执行();, 故会报错;
当js执行到(function {// code})();时, 由于(function {// code})是表达式, js会去对它求解得到返回值, 由于返回值是一 个函数, 故而遇到();时, 便会被执行.
另外, 函数转换为表达式的方法并不一定要靠分组操作符(),我们还可以用void操作符,~操作符,!操作符……

1.插件demo

/*1、闭包区域,防止插件“污染”*/
(function($){
    /*定义默认参数*/
    var defaults = {foreground:'red', background:'yellow'};

    /*2、扩展jQuery方法,制作插件, extend(obj) , obj => {"":"", "":""}*/
    $.fn.extend({
        "highLight":function (options) {
            var opts = $.extend({}, defaults, options);

            //这里需要返回jQuery的链式调用
            return this.each(function () { //this指的jQuery对象
                var $this = $(this);

                //根据参数来设置dom的样式
                $this.css({backgroundColor:opts.background, color:opts.foreground});
            })
        }
    });
})(window.jQuery);

调用:

    $(function() {
        $("p").highLight();
    });

2. fn扩展demo

//去掉前后的逗号: 1,2,3,str不可以为''
String.prototype.TrimStr = function (str) {
    var value = this;
    if (this.startsWith(str)) {
        value = value.substring(str.length);
    }
    if (this.endsWith(str)) {
        value = value.substring(0, value.length - str.length);
    }
    return value;
}

var str1 = " ,123434, ";
var ss1 = str1.TrimStr(', ');
var ss2 = str1.TrimStr('4,');
原文地址:https://www.cnblogs.com/SmileSunday/p/9209179.html