jquey插件开发
1.概述
jquery插件开发的主要方法有三种:
1、通过$.extend()来扩展jQuery,即在jQuery命名空间下扩展属性,直接在$对象下调用,不需要再dom下调用,也无法在dom元素下调用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="text">测试</div>
</body>
<script src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//jQuey插件开发方法1,在jQuery命名空间下新增属性
$.extend({
sayHello: function(name){
alert(name);
}
});
$.sayHello('gaoxiong');
//下面两者都相等,说明 $.fn = $.prototype
console.log($.fn);
console.log($.prototype);
//下面说明了通过 $.extend来扩展jQuery的方法,并不是扩展jquery的原型对象
console.log($.fn.sayHello);//undefined
$('#test').sayHello('gaoxiong'); //报错
</script>
</html>
用途:该方法适合用来定义一些辅助方法,类似与$.ajax()等非操作dom元素的方法,为什么时辅助方法?因为现在jquery被利用的主要目的就是操作dom。但这种方式无法利用jQuery强大的选择器带来的便利,要处理DOM元素以及将插件更好地运用于所选择的元素身上,还是需要使用第二种开发方式。
2、$.fn.extend方法扩展 $.prototype
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1 id="h1">测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//jQuery插件方法二:$.fn.extend(),顾名思义,该方法是在jQuery的原型对象上新增一个方法
$.fn.extend({
returnThis: function(){
return this;
}
});
//可以得出,上面的this 是一个集合(类似于数组),集合中包含了所有匹配的元素(这些元素为原生JS dom元素)
console.log($('#h1').returnThis());
console.log($('h1').returnThis());
//将会打印一个原生dom
console.log($('h1').returnThis()[0])
//综述:在自定义插件内部中的 this 可以理解为 匹配的元素的集合(jQuery的包装对象),这个集合的原型指向$.fn
//自定义一个设置字体颜色插件
$.fn.extend({
setcolor: function(colorName){
this.css('color', colorName);
}
});
//所有h1标签变为红色
$('h1').setcolor('red');
</script>
</html>
3、关于插件内this的指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="http://www.webo.com/liuwayong">我的微博</a>
</li>
<li>
<a href="http://http://www.cnblogs.com/Wayou/">我的博客</a>
</li>
<li>
<a href="http://wayouliu.duapp.com/">我的小站</a>
</li>
</ul>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//上一节,我们已经知道this 指代jQuery选择器返回的集合(包装对象)
//$.each()方法可以处理合集中的每个元素,但在each方法内部,this指的是普通的DOM元素,如果调用jQuery的方法那就需要用$来重新包装一下
//案例,我希望在每个a标签后面显示url地址
$.fn.extend({
showUrl: function(){
this.each(function(){
console.log(this);//原生dom元素
$(this).append($(this).attr('href'));
})
}
});
$('a').showUrl();
//使用jQuery命名空间时, this的指向为一个函数(包装dom为jQuery包装对象)
$.extend({
consoleThis: function(){
console.log(this);
}
})
$.consoleThis();
</script>
</html>
4、支持链式调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h2>测试</h2>
<h2>测试</h2>
<h2>测试</h2>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//jQuery中一个非常简便的方法是支持链式调用
$.fn.extend({
setColor: function(colorName){
//如下的这种写法为便捷写法
return this.each(function(){
$(this).css('color', colorName)
})
}
});
$('h1').setColor('red').css('background', 'blue');
//未设置链式调用(未在插件中返回this)
$.fn.extend({
setFontSize: function(size){
this.css('font-size', size);
}
})
//因为未在插件中返回this,那么$('h2').setFontSize('50px')为一个undefined,如下会报错
$('h2').setFontSize('50px').css('background', 'yellow');
</script>
</html>
5、设置默认参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>测试</h1>
<h1>测试</h1>
<h2>测试</h2>
<h2>测试</h2>
</body>
<script src='lib/jquery-1.8.3.min.js'></script>
<script type="text/javascript">
//设置默认参数,先学会$.extend(obj1, obj2)
var DEFAULTS = {
age: 25,
name: 'gaoxiong'
};
var options = {
age: 24,
name: 'jiaojiao'
};
var settings = $.extend(DEFAULTS, options);
console.log(settings);//age=>24, name=>jiaojiao
console.log(options);//不变
console.log(DEFAULTS);//与setting一样
$.fn.extend({
setColor: function(options){
var defaults = {
fontSize: '50px',
color: 'blue'
};
var settings = $.extend(defaults, options);
return this.css(settings);
}
});
$('h1').setColor();
$('h2').setColor({
color: 'red',
fontSize: '12px'
})
</script>
</html>
6、保护默认参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>测试</h1>
<h1>测试</h1>
<h2>测试</h2>
<h2>测试</h2>
</body>
<script src='lib/jquery-1.8.3.min.js'></script>
<script type="text/javascript">
//保护好默认参数,在一个插件中,默认参数可能被使用多次,上述方法会修改默认配置参数
//$.extend({}, defaults, options)避免了默认配置的修改
var defaults = {
age: 25,
name: 'gaoxiong'
};
var options = {
age: 25,
name: 'jiaojiao'
};
var setiings = $.extend({}, defaults, options);
console.log(setiings); // name => jiaojiao
console.log(defaults); // name => gaoxiong ,并没有修改defaults
</script>
</html>
7、面向对象的插件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>测试</p>
<p>测试</p>
<p>测试</p>
<div>测试</div>
<div>测试</div>
<div>测试</div>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//面向对象的插件开发,当项目变大或者版本迭代时,方便维护,结构清晰化
//定义一个类
var Beautifier = function(element, options){
this.$element = element;
this.defualts = {
color: 'red',
fontSize: '20px',
textDecoration: 'none'
};
this.options = $.extend({}, this.defualts, options);
};
//添加原型方法
Beautifier.prototype = {
beautify: function(){
return this.$element.css({
color: this.options.color,
fontSize: this.options.fontSize,
textDecoration: this.options.textDecoration
})
}
};
//将方法挂载到$.fn
$.fn.extend({
beautify: function(options){
return this.each(function(){
new Beautifier($(this), options).beautify();
})
}
})
//使用
$('p').beautify().css('background', 'blue');
$('div').beautify({
color: 'green',
fontSize: '100px',
textDecoration: 'decoration'
})
</script>
</html>
8、命名空间变量污染
不仅仅是jQuery插件的开发,我们在写任何JS代码时都应该注意的一点是不要污染全局命名空间,常用的方法是 用自调用匿名函数包裹你的代码。
匿名函数避免命名空间污染的原理:JavaScript中无法用花括号方便地创建作用域,但函数却可以形成一个作用域,域内的代码是无法被外界访问的。如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,同时不会和别的代码冲突。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p>测试</p> <p>测试</p> <p>测试</p> <div>测试</div> <div>测试</div> <div>测试</div> </body> <script src="lib/jquery-1.8.3.min.js"></script> <script type="text/javascript"> (function(){ var Beautifier = function(element, options){ this.$element = element; this.defualts = { color: 'red', fontSize: '20px', textDecoration: 'none' }; this.options = $.extend({}, this.defualts, options); }; Beautifier.prototype = { beautify: function(){ return this.$element.css({ color: this.options.color, fontSize: this.options.fontSize, textDecoration: this.options.textDecoration }) } }; $.fn.extend({ beautify: function(options){ return this.each(function(){ new Beautifier($(this), options).beautify(); }) } }) })(); $('p').beautify().css('background', 'blue'); $('div').beautify({ color: 'green', fontSize: '100px', textDecoration: 'decoration' }) </script> </html>
9、将系统变量以参数形式传递到插件内部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
<script src="lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//经过我前面8小节的复习,开发插件好像已经完美了,实际上还有一些细节需要处理
//1. 将这段代码放到页面后,前面别人写的代码没有用分号结尾
//2. 前面的代码将window, undefined等这些系统变量或者关键字修改掉了
//第一种情况
//别人的代码,这里没有使用分号结尾
var foo = function(){
}
//我写的代码
;(function(){
alert('Hello!');
})();
//原因:充当自调用匿名函数的第一对括号,与上面别人定义的函数相连,导致组成希望的两个语句 组成了一个语句,出现语法错误
//解决方法:在匿名函数包裹的圆括号前加分号
//第二种情况:将系统变量以参数形式传递到插件内部。这样做之后:
//1. window等系统变量在插件内部就有了一个局部的引用,可以提高访问速度,会有些许性能的提升
//2. 而至于这个undefined,为了得到没有被修改的undefined,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以‘undefined'那个位置接收到的就是真实的'undefined'了。
//其实上述两个解决办法,在jQuery这个库中本来就有使用到
//正式版本:一个安全,结构良好,组织有序的插件编写完成。
;(function($, window, document, undefined){
alert('Hello!');
})(jQuery, window, document);
</script>
</html>
10、代码编写规范
1、变量定义
- 做法:把将要使用的变量名用一个var关键字一并定义在代码开头,变量名间用逗号隔开
- 原因:
- 一是便于理解,了解下面的代码会用到哪些变量,同时代码显得整洁且有规律,也方便管理,变量定义与逻辑代码分开。
- 二是因为JavaScript中所有变量及函数名会自动提升,也称之为JavaScript的Hoist特性,即使你将变量的定义穿插在逻辑代码中,在代码解析运行期间,这些变量的声明还是被提升到了当前作用域最顶端的,所以我们将变量定义在一个作用域的开头是更符合逻辑的一种做法。
2、变量及函数命名
- 做法:一般使用驼峰命名法(CamelCase),即首个单词的首字母小写,后面单词首字母大写,比如 showButton。
3、常量命名
- 做法:对于常量,所有字母采用大写,多个单词用下划线隔开,比如WIDTH=100,BRUSH_COLOR='#00ff00'。
4、当变量为jQuery类型时
- 当变量是jQuery类型时,建议以$开头,开始会不习惯,但经常用了之后会感觉很方便,因为可以很方便地将它与普通变量区别开来,一看到以$开头我们就知道它是jQuery类型可以直接在其身上调用jQuery相关的方法,比如var $element=$('a'); 之后就可以在后面的代码中很方便地使用它,并且与其他变量容易区分开来。
5、引号的使用
- 引号的使用:一般HTML代码里面使用双引号,而在JavaScript中多用单引号。
浙公网安备 33010602011771号