不是原创哦,笔记是照着下面这个博客地址写的,https://www.cnblogs.com/ajianbeyourself/p/5815689.html,非常感谢!
jQuery插件开发模式
主要有三种:
- 通过$.extend()来扩展jQuery
- 通过$.fn向jQuery添加新的方法
- 通过$.widget()应用jQuery UI的部件工厂方式创建
通常我们使用第二种方法。第三种方法是用来开发更高级的jQuery部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态信息自动保存,各种相关插件的使用方法等,这里不细说。
第一种方式他检点,仅仅是在jQuery命名空间或者理解成在jQuery身上添加了一个静态方法而已。通过$.extend()添加的函数,直接通过$.函数名
调用就可以了。
$.extend({
sayHello:function(name){
console.log('Hello '+(name?name:'Dude')+'!');
}
})
$.sayHello();
$.sayHello('lianlian');
运行结果:
Hello Dude!
Hello lianlian!
这种方式定义一些辅助方法是比较方便的,比如自定义一个console,输出特定格式的信息,定义一次后可以通过jQuery在任何需要的地方调用它。
$.extend({
log:function(message){
var now = new Date(),
y = now.getFullYear(),
m = now.getMonth() + 1;
d = now.getDate(),
h = now.getHours(),
min = now.getMinutes(),
s = now.getSeconds(),
time = y + '/' + m + '/' + d + ' ' + h + ':' + min + ':' + s;
console.log(time+' My app '+message);
}
})
$.log('intializing....');
运行结果:
2018/8/15 14:15:14 My app intializing….
插件开发
采用第二种方式进行插件开发
基本格式:
$.fn.pluginName = function(){code}
就是往$.fn上面添加一个方法,名字是我们的插件名。我们的差价代码在这个方法里展开。
比如我们将页面上所有的连接变成红色,插件写法:
$.fn.myPlugin = function(){
// this指的是用jQuery选中的元素
// 比如this = $('a')
this.css('color','red');
}
在插件名字定义的这个函数内部,this指代的是我们在调用该插件时,用jQuery选择器选中的元素,一般是一个jQuery类型的集合,比如$(‘a’)返回的是页面上所有a标签的集合,且这个集合已经是jQuery包装类型了,也就是说,在对其进行操作的时候可以直接调用jQuery的其他方法而不需要再用美元符号来包装了。
现在我们可以去页面调试代码了。
<ul>
<li><a href="https://github.com/byLianLian">我的github</a></li>
<li><a href="https://blog.csdn.net/weixin_40712618">我的博客</a></li>
<li><a href="https://blog.csdn.net/weixin_40712618">我的博客</a></li>
</ul>
<p>p标签不收影响</p>
<script src="js/jquery-1.12.2.min.js"></script>
<script>
$.fn.myPlugin = function(){
// this指的是用jQuery选中的元素
// 比如this = $('a')
this.css('color','red');
}
$(function(){
$('a').myPlugin();
})
</script>
运行结果:
上面是对一个集合进行处理,下面我们对每个元素今次那个处理,就用到了jQuery的each()方法,each()方法内部,this指的是普通的DOM元素,所以要用$转换一下。
$.fn.myPlugin = function(){
// this指的是用jQuery选中的元素
// 比如this = $('a')
this.css('color','red');
this.each(function(){
$(this).append(' '+$(this).attr('href'));
})
}
支持链式调用
我们都最后到jQuery支持链式调用,为了让插件不打破这种链式调用,只需要return一下。
$.fn.myPlugin = function(){
// this指的是用jQuery选中的元素
// 比如this = $('a')
this.css('color','red');
return this.each(function(){
$(this).append(' '+$(this).attr('href'));
})
}
让插件接收参数
一个强劲的插件时可以让使用者随意定制,这要求我们在编写插件时考虑的全面一些,尽量提供合适的参数。
比如我们不想让插件只变成红色,想让插件的使用者来定义使用什么颜色,要做到这一点,只需要使用者在调用时传入一个参数即可,同时,我们在插件的代码里接收。另一方面,为了灵活,使用者可以不传递参数,插件里面会给出默认值。
我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了的值的参数使用指定值,未指定的参数使用插件的默认值。
再添加一个fontSize值,允许插件使用的时候设置字体大小。
$.fn.myPlugin = function(options){
var defaults={
'color':'red',
'fontSize':'12px'
};
var settings = $.extend(defaults,options);
return this.css({
'color':settings.color,
'fontSize':settings.fontSize
})
}
$(function(){
$('a').myPlugin({'color':'#2c9929'});
})
运行结果:
同时指定颜色和大小:
$('a').myPlugin({'color':'#2c9929','fontSize':'20px'});
保护好默认参数
上面extend会将defaults的值改变,这样不行,因为有些插件应该保持原来的样子,如果再使用的话,是被更改的值,就不能用默认值了。
解决办法是,将一个新的空队形作为$.extend的第一个参数,defaults和用户传入的options紧随其后,这样做的好处是所有的值被合并到这个空对象中,保护了插件里面的默认设置。
$.fn.myPlugin = function(options){
var defaults={
'color':'red',
'fontSize':'12px'
};
var settings = $.extend({}, defaults,options);//将空对象作为第一个参数
return this.css({
'color':settings.color,
'fontSize':settings.fontSize,
'textDecoration':this.options.textDecoration
})
}
$(function(){
$('a').myPlugin({'color':'#2c9929'});
})
面向对象的插件开发
为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另一个方法的时候,再去定义另一个function,同样在需要变量的时候,毫无规则的定义一些散落在代码各处的变量。这样不方便维护,也不够清晰。
如果将重要的变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为所有的变量名还有方法名都在对象的内部。
我们把上面的插件抽象成一个美化页面的对象。我们新建一个对象命名为Beautifier,然后在插件里使用这个对象来编码。
// 定义Beautifier的构造函数
var Beautifier = function(ele,opt){
this.$element = ele,
this.defaults = {
'color':'red',
'fontSize':'12px',
'textDecoration':'none'
},
this.options = $.extend({},this.defaults,opt);
}
// 定义Beautifier的方法
Beautifier.prototype = {
beautify:function(){
return this.$element.css({
'color':this.options.color,
'fontSize':this.options.fontSize,
'textDecoration':this.options.textDecoration
})
}
}
// 在插件中使用Beautifier对象
$.fn.myPlugin = function(options){
//创建Beautifier的实体
var beautifier = new Beautifier(this, options);
// 调用其方法
return beautifier.beautify();
}
通过上面的改造,我们的代码边的更面向对象了,也更好维护和理解,以后要加新功能,新方法,只需要向对象添加新变量及方法即可,然后在插件里实例化后即可调用新添加的东西。
插件的调用还是一样的。
$(function(){
$('a').myPlugin({
'color':'#2c9929',
'fontSize':'24px'
});
})
若想指定文字带下划线
(function(){
(function(){
(‘a’).myPlugin({
‘color’:’#2c9929’,
‘fontSize’:’24px’,
‘textDecoration’:“underline”
});
})
关于命名空间
不仅仅是jQuery插件的开发,我们在写任何JS代码时都应该注意的一点是不要污染全局命名空间。因为随着你的代码增多,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也容易跟别人写的代码有冲突。所以不到万不得已,一般我们不会将变零设为全局变量。
一个好的做法是时钟使用自调用匿名函数包裹代码,这样就可以完全放心,安全的将它用于任何地方了,绝对没有冲突。
用自调用匿名函数包裹代码
我们知道JavaScript中无法使用花括号方便的创建作用域,但函数内部却可以形成一个作用域,域内的代码时无法被外界访问的。如果我们将自己的代码放入一个函数中,name就不会污染全局命名空间,同时不会和别人的代码产生冲突。
上面我们定义了Beautifier全局变量,他会被赋值到window对象上,为了防止这种事情发生,我们可以把代码放到jquery插件的代码中,但是这样会让插件变的臃肿,在$.fn.myPlugin中我们更应该关注插件的调用以及与jquery的互动。
所以我们保持原来的代码不变,将所有的代码用自调用匿名函数包裹。
// 定义Beautifier的构造函数
(function(){
var Beautifier = function(ele,opt){
this.$element = ele,
this.defaults = {
'color':'red',
'fontSize':'12px',
'textDecoration':'none'
},
this.options = $.extend({},this.defaults,opt);
}
// 定义Beautifier的方法
Beautifier.prototype = {
beautify:function(){
return this.$element.css({
'color':this.options.color,
'fontSize':this.options.fontSize,
'textDecoration':this.options.textDecoration
})
}
}
// 在插件中使用Beautifier对象
$.fn.myPlugin = function(options){
//创建Beautifier的实体
var beautifier = new Beautifier(this, options);
// 调用其方法
return beautifier.beautify();
}
})();
这样做还要一个好处是,自调用匿名函数里面的代码会在第一时间执行,页面准备好后,上面的代码就将插件准备好了,以方便在后面的代码中使用插件。
将系统变量一变量形式传递到插件内部
var foo = function(){
// 内容
}
(function(){
//我们的内容
})();
会发现错误:
这是因为用来充当自调用匿名函数的第一对括号与上面别人定义的函数相连,因为中间没有分号,解析错误。所以我们要习惯在代码的开头添加一个分号,养成一个良好的习惯。
var foo = function(){
// 内容
}
;(function(){
//我们的内容
})();
同时,将系统变量以参数的形式传递到插件内部也是个不错的时间。当我们这样做之后,window等系统变量在插件内部就有了一个局部的引用,可以提高访问速度,会有些许性能的提升。
// 定义Beautifier的构造函数
(function($,window,document,undefined){
var Beautifier = function(ele,opt){
this.$element = ele,
this.defaults = {
'color':'red',
'fontSize':'12px',
'textDecoration':'none'
},
this.options = $.extend({},this.defaults,opt);
}
// 定义Beautifier的方法
Beautifier.prototype = {
beautify:function(){
return this.$element.css({
'color':this.options.color,
'fontSize':this.options.fontSize,
'textDecoration':this.options.textDecoration
})
}
}
// 在插件中使用Beautifier对象
$.fn.myPlugin = function(options){
//创建Beautifier的实体
var beautifier = new Beautifier(this, options);
// 调用其方法
return beautifier.beautify();
}
})(jQuery,window,document);
这样一个安全,结构良好,组织有序的插件编写完成。
关于变量的定义和命名
变量定义:好的做法是把将要使用的变量名用一个var关键字一并写在代码的开头,变量名中间用逗号隔开。原因如下:
- 一是便于理解,知道下面的代码会用到哪些变量,同时代码显得整洁有规律,也方便管理,变量定义与逻辑代码分开。
- 二是因为JavaScript中所有变量及函数名会自动提升,即在代码解析运行期间,这些变量的声明还是被提升到了当前作用域的最顶端,把变量放在作用域的开头更符合逻辑。这只是一种约定,不是必须。
变量及命名函数:一般使用驼峰法,即首个单词的首字母小写,后面单词的首字母大写。常量所有字母大写,多个单词用下划线分开。jquery变量,一$开头,便于区分。
引号的使用:一般HTML代码里使用双引号,而在JavaScript中使用单引号。养成习惯,比较不容易出错。