2

JQ插件封装第一天

查看jq代码,发现好多方法都是使用$.fn来封装方法,但fn又是什么,控制台console后发现都是jq的方法
console.log($.fn)

clipboard.png

$.prototype===$.fn,结果为true

clipboard.png

clipboard.png

prototype:可以为对象添加方法和属性。
这样就可以理解为给jq原型添加方法及属性。

自己写个小例子:

1.实现字符串转int方法(同parseInt())
html:

<input type="text">

js:
//防止全局变量污染,影响其他插件
(function($){
    $.fn.isnum=function(str){
        //注意:操作this的时候这里已经是$(this),请使用jq的操作dom的方法。
        //不能使用value,应为val()
        //测试代码:this.get(0).value=((+str||str==0)?(+str):NaN)
        this.val((+str||str==0)?(+str):NaN);
        console.log(this.value);
    }
})(jQuery)
使用
$('input').isnum('0999');//999
$('input').isnum('99s');//NaN
2.求最大div高度
html:
<div style="width: 20px;" ></div>
<div style="width: 10px;"></div>
<div style="width: 21px;"></div>
<div style="width: 5px;"></div>
js:

// 求最宽的div

    (function($){
        $.fn.max_w = function(){
            var max = 0;
            $.each(this,function(i,item){
                max = Math.max(max,$(item).width());
            })
            return max;
        }
    })(jQuery)

    alert($('div').max_w())

JQ插件封装第二天

如上面如果封装方法过多,看起来会非常乱,这时可以使用jq的extend。

jQuery.extend( target [, object1 ] [, objectN... ] )
jQuery.extend( [ deep ], target , object1 [, objectN... ] )

参数 描述
deep 可选/Boolean类型指示是否深度合并对象,默认为false。如果该值为true,且多个对象的某个同名属性也都是对象,则该"属性对象"的属性也将进行合并。
target Object类型目标对象,其他对象的成员属性将被复制到该对象上。 object1 可选/Object类型第一个被合并的对象。
objectN 可选/Object类型第N个被合并的对象。

个人理解extend的作用就是把好多对象合并到一个对象里面,目前有三个以上参数,第一个是否深度合并,第二个合并到的目标,第三个被合并的对象,三个以后同第三个以此类推,通常只写一种参数即可:合并的object

下面做个测试:

var a = function(){
    console.log("a");
}
var b = function(){
    console.log("b");
}
var c = function(){
    console.log("c");
}
var f = new Object;
//把a,b,c放到一个对象合集然后合并到f对象里
$.extend(f,{a,b,c})
console.log(f);

结果:

clipboard.png

如果要合并到jquery对象中上面的$.extend(f,{a,b,c})需要把f改为$或者jquery,也可以直接省略该参数$.extend({a,b,c}),开发中就可以直接使用$.extend({a,b,c}),这样就可以对jq全局对象进行添加方法了.

一般开发中都是对某个实例进行添加方法,再看下第一天的test代码

(function($){
$.fn.isnum=function(str){
this.val((+str||str==0)?(+str):NaN); console.log(this.value); }
})(jQuery)

都是基于fn实例上添加方法,所以使用$.fn.extend(插件开发经常使用)
对上面的方法进行改写:

 (function($){
 $.fn.extend({
     isnum:function(str){
         this.val((+str||str==0)?(+str):NaN);
     },
     isNaN:function(){
         //…………
     }
  })
 
})(jQuery)
$('input').isnum('test')
总结:
在封装插件时常用$.fn.extend(对dom操作时).在封装像parsInt这样的方法时候适用于$.extend

上面差不多就满足了插件复用的基本需求了,但是,当你想在原来基础上添加内容,或者修改变量时,就需要传参来解决了。

写个测试:给文档div设置高度,宽度,背景及自定义css
html:<div>1</div><div>2</div><div>3</div><div>4</div>

js:

(function($){
            $.fn.extend({
                e_width:function(options){
                    var settings = $.extend({
                        width:'50px',
                        height:'20px',
                        background:'red'
                    },options);
                     this.each(function(){
                        $(this).css(settings);
                    });
                }
            })
        })(jQuery)
        $('div').e_width({
            'opacity':0.5,
            'cursor':'pointer'
        })

声明一个变量settins来初始化默认数据(即没有传参的默认状态),然后将opions形参合并到settins,最后作用到css中,所以在实例中添加参数就可以合并到settings中,完成自定义css,而且继续传参数会代替前面初始设置的值。

封装

(function(){
    $.extend({
    //变量在数组中是否存在,存在的位置
        areArray(b,arr){
            for(var i in arr){
                if(arr[i] == b){
                     return arr[i]+'所在位置'+i;
                }
            }
        },
        unrepeat(arr){
        //unrepeat 数组去重,返回去重后的数组
            for(var i =0;i<arr.length;i++){
                for(var j = i+1;j<arr.length;j++){
                    if(arr[i]==arr[j]){
                        arr.splice(i,1)
                    }
                }
            }
            return arr;
        },
        isnum(str){
        //字符串是否可以转为数字
            return (+str||str==0)?true:false;
        }
    })
})();


a2774206
1.8k 声望26 粉丝

You can't forget your role at all times