自定义jQuery插件Step by Step
1.1.1 摘要
随着前端和后端技术的分离,各大互联网公司对于 Mobile First理念都是趋之若鹜的,为了解决网页在不同移动设备上的显示效果,其中一个解决方案就是Responsive Design;但我们今天不是介绍它,正由于前端开发已经十分重要了,所以我们将介绍如何使用jQuery自定义插件。
相信大家都使用过jQuery库,甚至自定义过一些常用的jQuery插件,如果没有学习过也无需担心,接下来我们将从一些简单的例子开始。
本文目录
1.1.2 正文
现 在,jQuery库的功能已经很丰富了(The Write Less, Do More, JavaScript Library),但它也没有办法满足用户的所有需求,所以,它提供了一种机制:让用户给核心模块增加自定义的方法和额外的功能;通过这种机 制,jQuery允许我们创建自定义的插件封装常用的方法,从而提高我们的开发效率。
控件模式
jQuery插件定义方式很简单,如果我们需要定义一个插件,只需给jQuery的$.fn对象添加一个新的函数属性就可以了,示例代码如下:
$.fn.myPluginName = function() { // Your plugin logic. };
现在,我们定义了一个函数myPluginName(),这样就创建了一个自定义插件了,但有一个问题我们要注意的是:由于美元符号(“$”)不仅 仅只有jQuery库会使用到,其他Javascript库也可能使用到,假如其他库中“$”也有特别的含义,那么就会引起不必要冲突了。
其实,我们可以通过定义自执行的函数(IIFE),然后把jQuery对象作为参数传递给该自执行函数,通过建立“$”和jQuery的对应关系,这样“$”就不会在其执行范围中被其他库覆盖了。
(function($) {
$.fn.myPluginName = function() {
// your plugin logic
};
})(jQuery);
大家看到这里,我们的插件通过闭包的方式封装起来了,这是为了确保我们使用“$”符号和其他JavaScript库之间不会冲突。
上面我们通过匿名函数的方式给myPluginName()方法赋值,我们也可以通过另外一种方法来创建自定义方法,那就是使用jQuery的extend()方法,它允许我们定义多个方法,而且语意更加简洁,示例代码如下:
(function($) {
$.extend($.fn, {
myplugin: function() {
// your plugin logic
}
});
})(jQuery);
SignUp表单
现在,我们对jQuery自定义插件有了初步的了解,接下来,我们将通过具体的例子介绍自定义的jQuery插件的实现。
假设,我们需要定义一个表单校验的插件,也许有人会说:“jQuery已经提供了表单校验插件,我们真的有必要重做轮子吗?”,的确是这样,但这些插件功能十分丰富不利于刚开始的学习jQuery使用,我们更希望通过一个简单的例子介绍jQuery插件的定义。
我们有一个注册表单,它包含Name,Email,Password和Weibo等输入信息,现在,需要定义一个表单验证控件,验证用户的输入信息是否符合规则,表单的HTML代码如下:
<div class="validation-demo">
<!-- Start Sign Up Form -->
<form action="#signup-form" id="Form1">
<h2>Sign Up</h2>
<fieldset>
<div class="fieldgroup">
<label for="name">
Name</label>
<input type="text" name="name" validation="required"/>
</div>
<div class="fieldgroup">
<label for="email">
Email</label>
<input type="text" name="email" validation="email"/>
</div>
<div class="fieldgroup">
<label for="password">
Password</label>
<input type="text" name="password" validation="password"/>
</div>
<div class="fieldgroup">
<label for="weibo">
Weibo</label>
<input type="text" name="weibo" validation="url"/>
</div> <div class="fieldgroup">
<input type="submit" class="submit" value="Sign up">
</div>
</fieldset> <div class="fieldgroup">
<p>Already registered? <a href="http://www.cnblogs.com/rush">Sign in</a>.</p>
</div>
</form>
<!-- End Sign Up Form -->
</div>
现在,我们需要验证Password长度,Email地址和Weibo地址的合法性,首先我们在input标签中添加validation属性标记该输入是否需要验证,接着我们设置validation的值:required,email,password和url。
图1注册表单
Validation对象
接下来,我们要创建一个Validation类型(类)用于验证用户输入信息,它包含4个方法分别用于验证Name、Email、Password和Url地址信息。
(function($) { // The validation function.
// We adds validation rules for email, required field, password and url.
var Validation = function() { var rules = { email: {
check: function(value) { if (value)
return isValidatedPattern(value, /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/);
return true;
},
msg: "Please enter a valid e-mail address."
},
url: {
check: function(value) { if (value)
return isValidatedPattern(value, /^https?:\/\/(.+\.)+.{2,4}(\/.*)?$/);
return true;
},
msg: "Please enter a valid URL."
},
password: {
check: function(value) {
if (value.length < 8 || value.length > 20) {
return false;
}
else {
// Check the password strength enough.
return isValidatedPattern(value, /(?=[A-Za-z0-9]{8,20})(?=.*[A-Za-z])(?=.*[0-9])[A-Za-z0-9]+/);
}
},
msg: "Your password must be at least 8 characters long."
},
required: {
check: function(value) { if (value)
return true;
else
return false;
},
msg: "This field is required."
}
}
var isValidatedPattern = function(value, pattern) {
var regex = pattern;
var match = regex.exec(value);
return match;
} // Returns a publish method, then the user can custom validation rule.
return { addRule: function(name, rule) { rules[name] = rule;
},
getRule: function(name) { return rules[name];
}
}
} //Creates instance of our object in the jQuery namespace.
$.Validation = new Validation();
})(jQuery);
// We're passing jQuery into the function
// so we can use $ without potential conflicts.
上面,我们定义了一个Validation类型,通过一个私有的数组rules保存了验证Name、Email、Password和Url对象;每 个验证对象中都包含一个check()方法,如:email对象的check()方法,通过调用方法isValidatedPattern(),判断用户 输入是否符合验证规则。
接着,我们返回公开的方法addRule()和getRule(),让用户可以通过addRule()方法增加自定义的验证方法。
我们在Validation类型中定义了公开的方法addRule(),通过该方法我们可以添加自定义的验证方法,而无需修改我们的插件代码。
接下来,让我们添加自定义的验证方法,具体代码如下:
// Adds custom rule.
$.validation.addRule("CustomRule", {
check: function(value) {
if (value != "JK_Rush") {
return false;
}
return true;
},
msg: "Must equal to the word JK_Rush."
});
上面,我们通过addRule()方法添加了自定义的验证规则,由于addRule()方法是公开的,所以我们可以通过该方法往私有的rules数组添加自定义的验证规则。
表单对象
接下来,我们定义一个Form类型,它表示DOM中的表单实例。
// The Form type.
var Form = function(form) { var fields = []; // Find the field has the validation attribute.
form.find("[validation]").each(function() {
var field = $(this);
if (field.attr('validation') !== undefined) {
fields.push(new Field(field));
}
});
this.fields = fields;
} // The Field type.
var Field = function(field) { this.field = field;
this.valid = false;
//this.attach("change");
}
由于表单中有多个输入框,我们使用jQuery的each()方法来遍历表单中所有的输入框,查找到输入框中包含valiation属性的输入框,然后把field对象保存到fields数组中。
Javascript原型对象
ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
前面,我们创建一个类型Field用来表示表单中需要验证的输入框,那么Field实例对象必须有一个validate()方法,我们直接给Field对象添加validate()方法,具体实现如下:
var Field = function(field) { this.field = field;
this.valid = false;
//this.attach("change");
} Field.validate = function() {
// Your cdoe here.
}
我们注意到每当创建一个Field对象时,都会分配给该对象一个独立的validate()方法,如果我们创建30个Field对象,那么就要给这30对象分配30次validate()方法,其实,validate()方法应该是共享的,也就是说每个Field对象都应该调用用一个validate()方法;这时我们可以使用原型链方式共享validate()方法。
接下来,让我们将在Field的原型属性(prototype)中添加validate()方法,具体实现如下:
// The prototype of Field type.
Field.prototype = { // Public method.
attach: function(event) { // The object refers to Field object.
var obj = this; // When the field changed, then invoked the validate method.
if (event == "change") {
obj.field.bind("change", function() {
return obj.validate();
});
} // When Key up, then invoked the validate method.
if (event == "keyup") {
obj.field.bind("keyup", function() {
return obj.validate();
});
}
}, // Public method.
validate: function() { var obj = this,
field = obj.field,
errorClass = "errorlist",
errorlist = $(document.createElement("ul")).addClass(errorClass), // We can splits the validation attribute with space.
// Gets all validation types.
types = field.attr("validation").split(" "), // Gets the fieldgroud object.
container = field.parent(),
errors = []; // If there is an errorlist already present
// remove it before performing additional validation
field.next(".errorlist").remove(); for (var type in types) { var rule = $.Validation.getRule(types[type]); // If invalid displays the error msg.
if (!rule.check(field.val())) { container.addClass("error");
errors.push(rule.msg);
}
}
if (errors.length) { // Unbinds the keyup event added before.
obj.field.unbind("keyup") // Attaches the keyup event.
obj.attach("keyup");
field.after(errorlist.empty()); // Displays the error msg.
for (error in errors) { errorlist.append("<li>" + errors[error] + "</li>");
}
obj.valid = false;
}
else {
errorlist.remove();
container.removeClass("error");
obj.valid = true;
}
}
}
图2 Field原型对象
我们在Field的原型中添加了两个方法,attach()方法用来绑定验证输入框的keyup和change事件,而validate()方法封装了调用具体校验方法。
现在,每个Field对象都可以调用继承于原型的attach()和validate()方法,假设表单中包含30个需要校验的输入,那么我们该如何遍历每个Field对象并且调用其validate()方法呢?
其实,Field对象都包含在Form对象中,由于我们在Form类型中定义了fields属性,它存储了包含validation属性field对象,所以我们可以通过访问Form的fields属性遍历每个field对象。
这里我们给Form的原型添加两个方法,validate()用来校验表单对象中的field,isValid()方法判断field对象是否符合验证规则,如果不符合规则就把焦点定在该输入框中。
// The prototype of Form.
Form.prototype = { // Validates all the fields in the form object.
validate: function() { for (field in this.fields) { this.fields[field].validate();
}
}, // If the field invaild, focus on it.
isValid: function() { for (field in this.fields) { if (!this.fields[field].valid) { this.fields[field].field.focus();
return false;
}
}
return true;
}
}
图3 Form原型对象
插件使用
现在我们给Form对象添加了validate()和isValid()方法,接下来,我们将使用jQuery的扩展方法($.extend),使所有的jQuery对象都可以访问我们自定义的插件方法。
// Extends jQuery prototype with validation and validate methods.
$.extend($.fn, { validation: function() { // Creates a Form instance.
var validator = new Form($(this)); // Stores the Form instance in Key/Value collection.
$.data($(this)[0], 'validator', validator); // Binds the submit event.
$(this).bind("submit", function(e) {
validator.validate();
if (!validator.isValid()) {
e.preventDefault();
}
});
}, // Checks the field is validated or not.
validate: function() { var validator = $.data($(this)[0], 'validator');
validator.validate();
return validator.isValid(); }
});
我们在jQuery的扩展方法($.extend)中添加了两个方法,它们分别是validation()和 validate();validation()创建了一个Form对象,接着绑定了页面的submit事件,当页面方式提交时,验证表单输入是否正确。
现在,我们已经完成了自定义的jQuery插件了,那么接下来我们将使用该插件验证signupform。
我们在表单的HTML中引入jQuery库和自定义插件,具体代码如下:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.formvalidation.js"></script>
当然我们也把jQuery库下载到本地,然后引入到我们项目中。
接下来,我们在HTML页面中添加以下代码:
$(function() { // jQuery DOM ready function. // Get the form object.
var signUpForm = $("#signup-form"); // Invokes the validation method.
signUpForm.validation();
});
当DOM加载完毕后,就调用validation验证插件,当用户对页面进行提交或输入框的修改都会触发validate()方法。
1.1.3 总结
本文介绍了如何自定义jQuery插件,首先介绍了jQuery插件的定义方式,通过给jQuery的$.fn方法添加自定义方法来实现我们的插件。
接着,我们引入了表单验证控件例子来介绍jQuery插件的实现;我们在插件中定义了Form和Field类型,然后通过原型链方式共享Form和Field的方法,使得每个Form或Field对象实例可以调用其共享的方法。
希望大家在阅读本博文后,对jQuery插件的实现有进一步的了解。
参考
关于作者:[作者]:JK_Rush从事.NET开发和热衷于开源高性能系统设计,通过博文交流和分享经验,欢迎转载,请保留原文地址,谢谢。 |
自定义jQuery插件Step by Step的更多相关文章
- 使用自定义 jQuery 插件的一个选项卡Demo
前几天闲着没事,想着编写一个 jQuery 插件,或许这将是一个美好的开始. 这里是html页面: <!DOCTYPE html> <html lang="en" ...
- 如何创建一个自定义jQuery插件
简介 jQuery 库是专为加快 JavaScript 开发速度而设计的.通过简化编写 JavaScript 的方式,减少代码量.使用 jQuery 库时,您可能会发现您经常为一些常用函数重写相同的代 ...
- 【jQuery基础学习】08 编写自定义jQuery插件
目的:虽然jQuery各种各样的功能已经很完善了,但是我们还是要学会自己去编写插件.这样我们可以去封装一些项目中经常用到的专属的代码,以便后期维护和提高开发效率. jQuery插件的类型: 封装对象方 ...
- 1.ssm web项目中的遇到的坑--自定义JQuery插件(slide menu)
自定义的JQuery插件写的回调函数不执行: 写好了回调函数,将函数打印出来是原形,就是不执行 function () { console.log("---onClickItem---&qu ...
- 自定义Jquery插件——由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件
由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件下面是代码: // 掉用方式支持 $('select').textBeauty(1 ...
- 自定义JQuery插件之 beforeFocus
<html> <head> <title></title> <script type="text/javascript" sr ...
- 自定义jquery插件
参考:http://blog.csdn.net/bao19901210/article/details/21540137/ 自己看代码理解: <!DOCTYPE html> <htm ...
- jQuery插件编写规范
第一种方法: 在很多基于jQuery或基于Zepto的插件中,在立即函数执行前面会加上";"这个符号. 这是为了防止前面的其他插件没有正常关闭. 在立即执行函数执行时,会一般会传入 ...
- (翻译)编写属于你的jQuery插件
Writing Your Own jQuery Plugins 原文地址:http://blog.teamtreehouse.com/writing-your-own-jquery-plugins j ...
随机推荐
- Java_你应该知道的26种设计模式
四. 模板方法模式 Definition: Define the skeleton of an algorithm in an operation, deferring some steps to s ...
- Why And When To Use Pre-Update and Pre-Insert Triggers In Oracle Forms
Whenever we commit after entering data in Oracle Forms, many triggers fires during this event and al ...
- [HDOJ1175]连连看
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 连连看 Time Limit: 20000/10000 MS (Java/Others) ...
- CentOS 6.5 64位下安装MySQL 5.7.11
昨天花了一下午在CentOS6.5 上安装了MySQL,版本为5.7.11,下面介绍一下我安装时候出现的问题 以及解决方法,供大家参考. 1/清除残留 rpm -qa | grep mysql // ...
- poj 1106 Transmitters (叉乘的应用)
http://poj.org/problem?id=1106 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4488 A ...
- HDU 2098 分拆素数和
HDU 2098 分拆素数和 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768K (Java/Others) [题目描述 ...
- So easy Webservice 5.WSDL 文件说明
WSDL – WebService Description Language – Web服务描述语言 通过XML形式说明服务在什么地方-地址. 通过XML形式说明服务提供什么样的方法 – 如何调用. ...
- 查询计划Hash和查询Hash
查询计划hash和查询hash 在SQL Server 2008中引入的围绕执行计划和缓冲的新功能被称为查询计划hash和查询hash.这是使用针对查询或查询计划的算法来生成二进制hash值的二进制对 ...
- Java的内存分配策略
简单来说,对象内存分配主要是在堆中分配.但是分配的规则并不是固定的,取决于使用的收集器组合以及JVM内存相关参数的设定 以下介绍几条基本规则(使用的ParNew+Serial Old收集器组合): 一 ...
- iOS - OC NSString 字符串
前言 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding> @interface NSM ...