1、前言
虽然开发插件听着很高大上,但实际上只不过是一个功能的封装而已,实现的原理也异常简单,难的是参数的处理及功能的实现。对于参数,要尽可能多的考虑到哪些要素要处理成参数。
接下来会先讲解插件的实现原理,然后介绍一下jq
中插件的开发流程,最后展示一个小插件来帮助大家理解。
2、jq
插件原理
- 开发jq插件的核心:
$.extend()
— 将自定义函数或属性,绑定到jQuery
对象身上$.fn.extend()
— 将自定义函数或属性,绑定到jQuery
的DOM
对象身上
【注】在
jQuery
中使用jQuery()
与$()
是等价的,一般情况下均使用$()
👇老规矩,先看一个小案例来会会这个extend
// 既然是使用jQuery,那一定得先引入jQuery,那这边就先假装已经引入过了
let obj1 = {
a:'welcome',
b:'to'
}
let obj2 = {
c:'myBlogs',
d:function(){
console.log('welcome to my blog');
}
}
obj3 = $.extend(objOrigin,objPrev);
console.log(obj1); // {a: "welcome", b: "to", c: "myBlogs", d: ƒ}
console.log(obj2); // {c: "myBlogs", d: ƒ}
console.log(obj3); // {a: "welcome", b: "to", c: "myBlogs", d: ƒ}
console.log(obj1 === obj3); // true
👆通过上述结果可以看到:
$.extend()
把obj2
对象的属性和函数合并到了obj1
对象身上- 并且改变了
obj1
的数据,也就是说它是会改变原数据的 - 返回值
obj3
和合并后的原对象obj1
相等
👇既然jq
也是对象,那如果把属性和方法绑定在jq
身上,是不是也能通过jq
来执行
let obj4 = {
e:'hello jq',
fn:function(){
console.log('welcome to my blog')
}
}
$.extend(obj4);
console.log($.e); // hello jq
$.fn(); // welcome to my blog
👆在上述代码中,属性e
和函数fn
都绑定在了jQuery
身上,都能通过$
拿到值
- 也就是说,所谓的
jq
插件,就是将写好的功能通过$.extend()
绑定在jQuery
身上,在此基础上再优化下代码,一款自己开发的插件就新鲜出炉了。 - 而
$.fn.extend()
,就是将属性和方法绑在了jq
的DOM
元素身上
当然,绑定方式也有简写形式
1、$.extend()
的简写
- 绑定方式
$.extend({方法名/属性:功能/属性值})
$.方法名/属性:功能/属性值
- 执行方式
$.方法名()
2、$.fn.extend()
的简写
- 绑定方式
$.fn.extend({方法名/属性:功能/属性值})
$.fn.方法名/属性:功能/属性值
- 执行方式
$(jq的Dom元素).方法名()
下面详细介绍一下jq插件的开发流程。
3、jq
插件的开发流程
1、确定文件名:jquery.xxx.版本号.js
2、在js文件中开启匿名函数,并开启严格模式
3、私有化
4、在jquery身上绑定方法
5、处理参数
6、实现功能
1、一般来说,jq
插件都需要单独放一个文件里,并有一个固定形式的文件名,以jquery
开头,表明这是一个jquery
插件;接着是你插件的功能名,尽量语义化;由于插件也需要更新和迭代,那就需要一个版本号;最后当然是以js为后缀了。比如,下面我将给大家演示的的一个选型卡插件文件名:jquery.tab.1.0.js
2、开启匿名函数,是为了形成局部作用域,开启严格模式为了保证代码的安全性(注意在匿名函数的前面加上;
号)
;(function(){
'use strict'
})();
3、私有化:
上面提到过,在jQuery
中,都是以$
代替jQuery
的,但是$
作为一个符号也有许多其他含义,并且,如果用户或者你自己在全局作用域中不小心声明了一个$
的变量,就会影响到局部作用域中$
的含义。为了安全,所以要进行私有化
;(function($){ // 定义时接收一个$的参数(不能改,必须是$)
'use strict'
})(jQuery); // 执行时,传入一个jQuery参数(不能改,必须是jQuery)
4、在jQuery
身上绑定方法:上面的绑定方式
5、处理参数:尽量多的考虑使用场景,哪些元素要处理成参数
6、实现功能
3、选项卡插件开发
分析一下需要哪些参数:
1、肯定需要按钮
2、触发按钮,会有对应的显示内容
3、触发按钮形式可能会处理成点击或者鼠标进入
4、默认第几个内容是显示的,可能需要一个索引
5、选中显示的样式也可以是不同的
👇html
页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none
}
.box {
width: 400px;
height: 300px;
border: solid 1px black;
margin: 20px auto;
}
.box ul {
display: flex;
background: #ccc;
height: 30px;
line-height: 30px;
text-align: center
}
.box ul li {
flex: 1
}
.box ul li.active {
background: red
}
.box .cont {
height: 270px;
display: none;
}
.box .cont1 {
background: #399;
}
.box .cont2 {
background: #339;
}
.box .cont3 {
background: #393;
}
.box .cont4 {
background: #993;
}
.box .cont.active {
display: block;
}
</style>
</head>
<body>
<div class="tab1 box">
<ul>
<li>手机</li>
<li>电脑</li>
<li>袜子</li>
<li>奶粉</li>
</ul>
<div class="contBox">
<div class="cont1 cont">华为,小米等等等等</div>
<div class="cont2 cont">华硕,戴尔,联想,华为等等</div>
<div class="cont3 cont">运动袜,丝袜,长袜等等</div>
<div class="cont4 cont">三鹿,蒙牛,伊利等等等</div>
</div>
</div>
<div class="tab2 box">
<ul>
<li>手机</li>
<li>电脑</li>
<li>袜子</li>
<li>奶粉</li>
</ul>
<div class="contBox">
<div class="cont1 cont">华为,小米等等等等</div>
<div class="cont2 cont">华硕,戴尔,联想,华为等等</div>
<div class="cont3 cont">运动袜,丝袜,长袜等等</div>
<div class="cont4 cont">三鹿,蒙牛,伊利等等等</div>
</div>
</div>
<!-- 引入jQuery -->
<script src="jquery.2.2.4.js"></script>
<!-- 引入自己开发的插件 -->
<script src="jquery.tab.1.0.js"></script>
<!-- 执行插件 -->
<script>
$(".tab1").table({
btns: $(".tab1").children("ul").find("li"),
conts: $(".tab1").children(".contBox").children(".cont"),
index: 0,
type: 0,
iNow: "active"
});
$(".tab2").table({
btns: $(".tab2").children("ul").find("li"),
conts: $(".tab2").children(".contBox").children(".cont"),
index: 3,
type: 1,
iNow: "active"
});
</script>
</body>
</html>
👇选项卡插件
;(function($) {
"use strict";
// 由于选项卡肯定是通过DOM元素触发的,因此这里选用绑定在DOM元素身上的绑定方式
$.fn.table = function(ops){
// 利用解构赋值解析参数
let {btns,conts,index=0,type=0,iNow} = ops;
// 处理默认事件
let eveType = type === 0 ? "click" : "mouseenter";
// 设置默认样式
btns.eq(index).addClass(iNow).siblings().removeClass(iNow);
conts.eq(index).addClass(iNow).siblings().removeClass(iNow);
// 根据用户传入的行为,添加切换功能
btns.on(eveType,function(){
$(this).addClass(iNow).siblings().removeClass(iNow);
conts.eq($(this).index()).addClass(iNow).siblings().removeClass(iNow);
})
}
})(jQuery);