jQuery API 学习小扎(下)
续,非DOM操作的部分,这里提供了很多小工具,但精华的部分还是关于回调对象和延迟对象。
AJAX事件
全局/辅助方法
jQuery 全局 Ajax 事件的所有处理程序,必须附加到
document上无论哪一个 Ajax 请求被发送,所有 Ajax 全局处理器都将被执行
$.ajax()或$.ajaxSetup()调用时,global选项设置为false时将不触发全局事件.serialize(JQ对象)、.serializeArray(array)和$.param(obj)均用来序列化格式:$.param(obj)=> URL查询字符串或 Ajax 请求.serializeArray(array)=> 返回 JSON 格式的字符串.serialize()=> 将表单元素的值编译成字符串
接口及快捷方式
- 由于浏览器的安全限制,大多数 Ajax 有同源政策限制:该请求不能成功地检索来自不同的域,子域或协议的数据
$.get(url [,data][,success(data,textStatus,jqXHR)][, dataType]),相当于12345678910$.ajax({url: url,data: data,success: success,dataType: dataType});$.get('test.html', function (data) { // 最常见用法// do something...});$.getJSON(url [, data][, success(data, textStatus,jqXHR)])请求 JSON 编码数据$.getScript(url [, success(data, textStatus, jqXHR)])请求 JavaScript 文件.load( url [, data] [, complete(responseText, textStatus, XMLHttpRequest)])
$('#result').load('ajax/test.html');$.post(url [, data] [, success(data, textStatus, jqXHR)] [, dataType])123$.post('test.php', { name: 'John', time: '2pm' }, function (data) {alert('Data Loaded: ' + data);});
核心及其他
jQuery对象
jQuery()- 等价于
$() $(selector [, context])通过提供的选择器检索 DOM 元素并返回 jQuery 对象$(this)可调用this指向元素的 jQuery 方法$('span', this)等价于$(this).find('span'), 用来为检索元素做限制范围$(原生DOM)将原生 DOM 转换成 jQuery 对象$('HTML')将 HTML 转换成 DOM 元素
- 等价于
如 jQuery 对象为空,则
.length属性为0,可用于检测 jQuery 对象是否为空当 HTML 为没有属性的简单标签,一般调用原生
.createElement(),其他情况用.innerHTML机制,在此过程中,浏览器可能过滤掉某些元素如<html>等。此外jQuery()要求 HTML 字符串是以<开头的字符串(即文本节点不能出现在HTML字符串前面)
jQuery.noConflict([removeAll])判断是否从全局作用域中内去除所有 jQuery 变量(包括 jQuery 本身)1234567jQuery.noConflict();(function ($) {$(function () {// 继续使用 $ 代表 jQuery});})(jQuery);// 其它库可以使用 $jQuery.when(deferreds)执行一个或多个对象的回调函数,Deferred(延迟)对象通常表示异步事件
实用工具
$.each()遍历一个数组或对象(原生或 jQuery)$.inArray()返回一个值在数组中的索引位置。如果该值不在数组中,则返回-1(类似原生.indexOf(),使用严格比较===)$.trim()去除字符串两端的空格$.map(array, callback)将一个数组中的所有元素转换到另一个数组中并返回(结果和原数组长度不一定相同)$.grep()返回数组中符合筛选的项,不影响原数组$.makeArray()将类似数组的对象转化为普通数组$.type()判断对象的类别(函数、日期、数组、正则等)$.isFunction()判断是否为函数$.isArray()判断是否为数组$.isNumeric()判断是否为数字$.isWindow(obj)判断是否为 window 对象(一般用来确认是否为浏览器窗口操作),$.isXMLDoc(node)判断是否为 XML 节点$.isEmptyObject()判断某个对象是否为空(不含包括原型内的任何属性/方法), 而$.isPlainObject()判断某个参数是否为用{}或new Object()建立的对象$.extend()将多个对象,合并到第一个对象,$.merge()合并两个数组内容到第一个数组(这两个方法均会改变第一个对象/数组)var newArray = $.merge([], oldArray);// 用作拷贝方法$.contains(container, contained)检查弟二个 DOM 元素是否为弟一个 DOM 元素(原生 DOM)的后代$.noop()返回一个空函数$.now()相当于new Date().getTime()$.parseJSON('JSON')解析严格的JSON返回JS对象,$.parseXML('XML')解析XML,$.parseHTML('HTML')将字符串解析到一个 DOM 节点的数组
DOM元素方法及内部构件
.get([index])检索匹配 jQuery 对象得到对应的 DOM 元素, 指定了index参数则会获取单个元素(类似$('selector')[index],但可以指定负值).index()与.get()正好相反, 接受节点返回其索引值.toArray()返回一个包含 jQuery 对象集合中的所有 DOM 元素的标准数组。$.fn.jquery返回当前使用 jQuery 的版本.length与.size()均为返回 jQuery 对象中元素的数量
回调对象
jQuery.Callbacks()函数返回一个全能的对象,此对象对管理回调列表提供了强大的方式。它能够增加、删除、触发、禁用回调函数回调对象类似于保存了一个回调函数列表,使用
fire方法时,将会按列表顺序分别传入参数调用这些函数
回调对象的方法,这些方法均返回绑定它的那个回调对象
this以实现链式调用callbacks.add( callbacks )用来向回调列表中添加一个回调或回调的集合callbacks.remove( callbacks )从回调列表中删除一个回调或回调集合callbacks.fire( arguments )传入指定的参数调用所有的回调callbacks.disable()禁用回调列表中的回调
$.Callbacks( flags )flags 的参数代如下(参数可同时传入多个,类似同时满足&&)'once'只能执行一次fire()'memory'保存前面fire传入的参数,后面加入的新回调会被自动传入前面保存的参数并执行'unique'一次只能添加一个回调,回调列表不出现重复回调'stopOnFalse'当一个回调返回false时中断调用
回调对象的最典型应用是快速实现一个 观察者模式(又叫订阅/发布)
1234567891011121314151617181920// 定义一个保存自定义事件的列表var taskList = {}jQuery.Task = function (id) {var task = id && taskList[id] // 取出对应任务if (!task) { // 若任务不存在,则创建callbacks = jQuery.Callbacks()task = {publish: callbacks.fire,subscribe: callbacks.add,unsubscribe: callbacks.remove};// 将任务加到事件列表if (id) {taskList[id] = task}}// 返回取得或创建的 taskreturn task}
延迟对象
关于延迟对象的具体用法,请参考
阮一峰的 jQuery 的 deferred 对象详解理解 jQuery 的延迟对象,可以从理解 Promise 开始,本质上是对 Promise 的封装实现
延迟对象是 jQuery 很多方法实现的基础,如 AJAX,对异步编程提供了统一风格的 API
如果一个方法的执行依赖于多个请求结果,那么使用延迟对象(Promise)将大大松散代码结构耦合并提高可读性
采用链式写法,因此可以方便地为一个操作添加多个执行回调,按添加顺序执行
1234$.ajax("test.html").done(function () {alert("哈哈,成功了!")} ).fail(function () {alert("出错啦!")} ).done(function () {alert("第二个回调函数!")} )$.when()方法可以为同一个方法添加多个回调(类似Promise.all()),它只接受 Deferred 对象作为参数1234// 下面两个 ajax 都成功了才会调用 done,只要有一个失败了就调用 fail$.when($.ajax("test1.html"), $.ajax("test2.html")).done(function () { alert("哈哈,成功了!")}).fail(function () { alert("出错啦!")})封装普通函数使其成为 Deferred 对象可以用
deferred.resolve()和deferred.reject()1234567891011121314151617181920var wait = function () {// 新建一个deferred对象,作为私有变量var dtd = $.Deferred() // 这里也可以放在外面,而非闭包方式,但这有可能被外部使用 dtd.resolve() 等触发状态改变// 封装一个耗时的请求$.get('/someurl', function (res) {if (res.code === 200) {dtd.resolve() // 请求成功} else {dtd.reject() // 请求失败}})return dtd // 返回闭包// 也可以使用 return dtd.Primose(),这样返回一个新的 Deferred 对象 不能被外部的方法触发改变原来的 dtd}// 现在 wait() 函数生成一个 Deferred 对象了,可以作为 $.when() 的参数啦$.when(wait()).done(function (){alert("哈哈,请求成功了!")}).fail(function (){alert("请求错啦!")})deferred.promise()会包装生成一个对象为 Deferred 对象,使其拥有 Deferred 接口以下是几种 API 的汇总用法
123456789$.when(wait()).then(function () {alert("成功时看到我")}, function () {alert("失败时看到我")}).done(function () {alert("成功时看到我")})// 以下三种失败方法等同,推荐用 .catch,与 ES6 一致.then(null, function () {alert("失败时看到我")}).fail(function () {alert("失败时看到我")}).catch(function () {alert("失败时看到我")}).always(function () {alert("成功或失败都看到我")})deferred.state()用来判断当前的 Promise 状态,返回下列三种字符串- ‘pending’ 尚未完成
- ‘resolved’ 被解决
- ‘rejected’ 被拒绝
总结
最后总结一下,jQuery 虽然简单易学,但毕竟是一门基于 JavaScript 的库,本质上还是要理解这个语言的核心。实际开发中,个人也进行了不少的思考,毕竟需要兼容低版本浏览器是不二之选。
但也有个血泪的教训就是,很多时候太依赖 jQuery 了,导致经常需要查找手册才知道原生的方法实现(毕竟哲学是 write less,do more)
- 相关书籍推荐
- 《锋利的jQuery》,精品国产书,毫无上手难度的一本书,对新手而言极为推荐,有很多精心设计的demo。
- jQuery基础教程(第4版),图灵出版的精品,虽然是基础教程,但后半部分讲解的内容,很多是需要一定的实战积累才能理解其巧妙,建议作为进阶书籍。