JQuery意义 - Why?
为什么要使用JQuery,从我个人来说,就是这么几点:
简化代码 + 统一行为 + 功能强大 + 搭配方便。
简化代码是从写代码的角度来说的,实现同样的功能,如果用JavaScript内置对象和函数去完成的话,需要写很多代码,而使用JQuery这种类库却很简洁,下面的例子会体现出来。
统一行为是从浏览器的兼容性的角度来说的,实现一个行为,如果用JavaScript内置对象和函数去完成的话,需要处理很多的兼容性问题,这个在前面我们已经见识过了,使用JQuery这种类库,我们就不需要(或者说不总是需要)去考虑兼容性问题了。
功能强大是从JQuery提供的功能的角度来说的,在众多的类库中,无疑JQuery提供了最为全面的功能,这一点促使它甚至成为了微软的御用类库,默认加到了Web工程中,不仅如此,只要是使用类库的网站,大部分选择的都是JQuery,在网站开发中使用JQuery基本变成了固定的模式。
搭配方便是从JQuery与其它的类库配合使用的角度来说的,使用JQuery这种以提供行为为主的类库配合上Bootstrap这类以提供布局为主的类库,简直可以说是页面开发的通吃组合。再加上另外两个兄弟,形成的"JQuery+Bootstrap+AngularJS+NodeJS"开发模式,几乎成为了当今最为热门的开发方式(最起码兄弟我是这么认为的)。
JQuery引用 - Where?
引用一个类库的方式大家已经很熟悉了,不再多说:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
这是引用CDN上的文件,通常大家也会把这个类库下载下来放到本地,然后引用。
不管引用的这个文件是哪的,上面这行代码基本上都是放到页面尾部。
把脚本放到页面尾部可以提高页面的加载速度,这也是基本常识了。
JQuery对象 - What?
JQuery最重要的概念,就是jQuery对象。它是一个全局对象,可以简写为美元符号$。也就是说,jQuery和$两者是等价的(下面的例子中使用的都是美元符号$,不过很多人认为,为了不和其它类库中定义的$函数冲突,最好还是使用jQuery函数)。
在网页中加载JQuery函数库以后,就可以使用jQuery对象了。JQuery全部的方法,都定义在这个对象上面。所以使用JQuery类库的第一步自然是获取jQuery对象。
前面我们讲DOM的时候说过,为了操作DOM,必须对HTML元素进行抽象,得到对应的JavaScript中的DOM对象,这样才能通过这些对象操作HTML。
同样的道理,jQuery对象就是所有HTML元素在JQuery类库中的抽象,所有的相关方法自然是定义在这个对象上。
当我首次使用JQuery的时候,我一直对$(selector)心存困惑,直到很久之后,我才豁然开朗,原来jQuery对象就是通过这个函数获取到的,函数的参数决定了获取到的jQuery对象。不过jQuery对象一不是一般的对象,它是包装了满足参数条件的所有DOM对象的一个类似于数组的对象,这是很重要的一个特征。
到这里,我们就有必要分清两个概念了:
JQuery对象与DOM对象。
通过上面我们知道它们都是JavaScript中的对象,具有不同的方法集。
DOM对象通过document获得,然后可以执行相关的操作;JQuery对象通过$()函数获得,然后可以执行相关的操作。
于是同样是在浏览器中编程,那么不可避免的,我们有时候是使用DOM编程,有时候是使用JQuery编程,这就涉及到了DOM对象与JQuery对象的转换,通常来说有如下方式:
从DOM对象转为JQuery对象,这个很简单,因为$函数的参数支持DOM对象直接传进来:
var domObj = document.getElementById('testDiv');
var jQueryObj = $(domObj);
而JQuery对象作为一个DOM对象的包装集,使用索引值的方式获取的就是DOM对象,如下面例子中的获取第1个元素:
var domObj = $('#testDiv')[0];
var domObj = $("#testDiv").get(0);
当然了,JQuery对象枚举的时候返回的也是DOM对象,如下所示:
$("#testDiv").each(function() { alert(this); });
这个例子中的this就是DOM对象。
JQuery模式 - How?
使用JQuery的步骤是:获取JQuery对象,执行相关操作。概括起来就是:
$(selector).action(parameters);
下面分别看看这两个部分:
1. 获取JQuery对象的途径 - 选择器selector
下面我们就来看看selector这个参数;selector参数可以是一个字符串,也可以是DOM对象。
使用DOM对象作为参数的话就是直接把DOM对象转换成jQuery对象,这个在上面已经总结过了。
字符串形式的selector是最主要的使用方式,它可以是下列的各种形式:
1)CSS选择器语法
这里只是给出一些常见的选择器的例子,完整的选择器列表参看后面的参考文档:
// 基础选择器
$('#testDiv') // 选择id为testDiv的元素,一般id在整个页面是唯一的
$('p') // 选择页面中所有的p元素
$('.big') // 选择页面中所有的CSS类为big的元素
// 选择器的与或关系
$('.big,p') // 选择页面中所有CSS类为big的元素和所有的p元素
$('p#testDiv') // 选择页面中所有的CSS类为big的p元素
// 层次选择器
$('form input') // 选择页面中所有的form元素下面的所有的input元素
$('form>input') // 选择页面中所有的form元素下面直接属于form的input元素
$('#name+img') // 选择页面中id为name的元素后面紧跟着的img元素
$('#name~img') // 选择页面中id为name的元素后面所有的img元素
// 各种条件的过滤器:索引值,内容过滤,属性过滤,子元素过滤
$('tr:first'), $('tr:last') // 选择第一行/最后一行表格
$('input:not(:checked)') // 选择页面中没有被checked的input,not后面的参数可以是任意的选择器
$('tr:even'), $('tr:odd') // 偶数行/奇数行
$('tr:eq(1)'),$('tr:gt(1)'), $('tr:lt(1)') // 满足条件的第二行/第二行后面的/第二行前面的
$(':header') // 所有h1, h2, h3元素
$('div:not(:animated)') // 所有没有在执行动画效果的div
$("div:contains('Name')") // 所有内容中含有Name字符串的div
$('div:has(p)') // 所有含有p元素的div
$('tr:hidden'), $('tr:visible') // 隐藏/显示的行
// 所有有id属性的div/id值为name的div/id值不为name的div
$('div[id]'), $("div[id='name']"), $("div[id!='name']")
// 所有id属性值以name开头/结尾/包含name的div
$("div[id^='name']"), $("div[id$='name']"), $("div[id*='name']")
// 满足多个属性条件的div
$("div[id='name'][name$='man']")
// 在每个ul中查找第2个li,nth-child后面的参数可以是even, odd, index值, 倍数如3n, 3n+1等等。
// 注意这个参数是从1开始的,而eq()是从0开始的。
$('ul li:nth-child(2)')
// 在每个ul的子元素中中查找第一个/最后一个li
$('ul li:first-child'), $('ul li:last-child')
// 表单选择器与过滤器:
// 选择所有的input/text/password...
$(':input'), $(':text'), $(':password'), $(':radio'), $(':checkbox')
$(':button'), $(':submit'), $(':image'), $(':reset'), $(':file')
// 选择启用/禁用/checked/选中的input,option
$(':input:enabled'), $(':input:disabled'), $(':input:checked'), $('select option:selected')
2)字符串形式的元素
如果直接在jQuery构造函数中输入HTML代码,返回的也是jQuery实例。
$('<li class="greet">test</lt>')
上面代码从HTML代码生成了一个jQuery实例,它与从CSS选择器生成的jQuery实例完全一样。唯一的区别就是,它对应的DOM结构不属于当前文档。
3)函数的第二个参数 - 限制查找范围
默认情况下,jQuery将文档的根元素(html)作为寻找匹配对象的起点。如果要指定某个网页元素(比如某个div元素)作为寻找的起点,可以将它放在jQuery函数的第二个参数。
$('li', someElement);
上面代码表示,只寻找属于someElement对象下属的li元素。someElement可以是jQuery对象的实例,也可以是DOM对象。
如果还以我们前面的DOM操作那一篇中长途查找与短途查找的分类来看,上面使用选择器的方式显然是属于长途查找的一种。
下面来看看短途查找的方式,这个和前面一样,事先要获取到一个jQuery对象,然后基于这个对象,再进一步缩小查找的范围(当$函数指定第二个参数的时候,也可以缩小查找范围,从这个方面来说,这种也算是短途查找吧),看例子:
// first方法返回结果集的第一个成员,last方法返回结果集的最后一个成员。
$("li").first()
$("li").last()
// next方法返回紧邻的下一个同级元素,prev方法返回紧邻的上一个同级元素。
// 如果next方法和prev方法带有参数,表示选择符合该参数的同级元素。
$("li").first().next()
$("li").last().prev()
$("li").first().next('.item')
$("li").last().prev('.item')
// parent方法返回当前元素的父元素,parents方法返回当前元素的所有上级元素(直到html元素)。
// parent, parents, children这三个方法都接受一个选择器作为参数。
$("p").parent()
$("p").parent(".selected")
$("p").parents()
$("p").parents("div")
// children方法返回选中元素的所有子元素。
$("div").children()
$("div").children(".selected")
// 等同于
$('div > *')
$('div > .selected')
// siblings方法返回当前元素的所有同级元素。
$('li').first().siblings()
$('li').first().siblings('.item')
// nextAll方法返回当前元素其后的所有同级元素,prevAll方法返回当前元素前面的所有同级元素。
$('li').first().nextAll()
$('li').last().prevAll()
当然除了这些与DOM操作类似的获取parent, child, sibling(兄弟节点)的操作外,JQuery还提供了其它的一些相当强大的过滤操作,例如:
// closest方法返回当前元素,以及当前元素的所有上级元素之中,第一个符合条件的元素。
// find方法返回当前元素的所有符合条件的下级元素。
$('li').closest('div')
$('div').find('li')
// add方法用于为结果集添加元素。
$('li').add('p')
// addBack方法将当前元素加回原始的结果集。
$('li').parent().addBack()
// end方法用于返回原始的结果集
$('li').first().end()
// filter方法用于过滤结果集,它可以接受多种类型的参数,只返回与参数一致的结果。
// 返回符合CSS选择器的结果
$('li').filter('.item')
// 返回函数返回值为true的结果
$("li").filter(function(index) {
return index % 2 === 1;
})
// 返回符合特定DOM对象的结果
$("li").filter(document.getElementById("unique"))
// 返回符合特定jQuery实例的结果
$("li").filter($("#unique"))
// not方法的用法与filter方法完全一致,但是返回相反的结果,即过滤掉匹配项。
$('li').not('.item')
// has方法与filter方法作用相同,但是只过滤出子元素符合条件的元素。
$("li").has("ul")
// 上面代码返回具有ul子元素的li元素。
上面代码中的需要说明两点:
第一点,例子中的find方法,选中所有div元素下面的li元素,等同于$('li','div')。由于这样写缩小了搜索范围,所以要优于$('div li')的写法。
第二点,是这种"$('li').last().prevAll()"链式调用,每个jQuery对象的方法结束时都会返回当前的jQuery对象,所以可以直接把方法串起来这样调用。
选择器的知识就总结这些了,用好选择器是JQuery的核心,兄弟我还需努力。
参考资料:
JQuery官方网站:
http://api.jquery.com/
JQueryUI官方网站:
http://jqueryui.com/
一个全面的教程:
http://kb.cnblogs.com/page/46450/