第3章 jQuery中的DOM操作

DOM是 Document Object Model的缩写,意思是文档对象模型。根据 W3CDOM 规范(http://www.w3.org/DOM),DOM是一种与浏览器、平台、语言无关的接口,使用该接口可以轻松地访问页面中所有的标准组件。简单来说,DOM解决了Netscape的JavaScript和Microsoft的JScript之间的冲突,给予了Web 设计师和开发者一套标准的方法,让他们能够轻松获取和操作网页中的数据、脚本和表现层对象。

3.1 DOM操作的分类

一般来说,DOM操作分为3个方面,即DOM Core(核心)、HTML-DOM和CSS-DOM。

1.DOM Core

DOM Core并不专属于JavaScript,任何一种支持DOM的程序设计语言都可以使用它。它的用途并非仅限于处理网页,也可以用来处理任何一种使用标记语言编写出来的文档,例如XML。

JavaScript 中的getElmentById()、getElementsByTagName()、getAttribute()和setAttribute()等方法,这些都是DOM Core的组成部分。

例如:

  • 使用DOM Core来获取表单对象的方法:

[插图]

  • 使用DOM Core来获取某元素的src属性的方法:

[插图]

2.HTML-DOM

在使用JavaScript和DOM为HTML文件编写脚本时,有许多专属于HTML-DOM的属性。HTML-DOM的出现甚至比DOM Core还要早,它提供了一些更简明的记号来描述各种HTML元素的属性。

例如:

  • 使用HTML-DOM来获取表单对象的方法:

[插图]

  • 使用HTML-DOM来获取某元素的src属性的方法:

[插图]

通过上面所说的方法,可以发现获取某些对象、属性既可以用DOM Core来实现,也可以使用HTML-DOM实现。相比较而言HTML-DOM的代码通常比较简短,不过它只能用来处理Web文档。

3.CSS-DOM

CSS-DOM是针对 CSS的操作。在JavaScript中,CSS-DOM技术的主要作用是获取和设置style对象的各种属性。通过改变style对象的各种属性,可以使网页呈现出各种不同的效果。

例如:设置某元素style对象字体颜色的方法:

[插图]

jQuery作为JavaScript库,继承并发扬了JavaScript对DOM对象的操作的特性,使开发人员能方便地操作DOM对象。下面详细介绍jQuery中的各种DOM操作。

3.2 jQuery中的DOM操作

为了能全面地讲解DOM操作,首先需要构建一个网页。因为每一张网页都能用DOM表示出来,而每一份DOM都可以看作一棵DOM树。构建的网页效果如图3-1所示。

[插图]

图3-1 构建的网页

HTML代码如下:

[插图]

根据上面的网页结构构建出一棵DOM树,如图3-2所示。

[插图]

图3-2 DOM结构

接下来,对DOM的各种操作都将围绕这棵DOM树而展开。

3.2.1 查找节点

使用jQuery在文档树上查找节点非常容易,可以通过在第2章介绍的jQuery选择器来完成。

1.查找元素节点

获取元素节点并打印出它的文本内容,jQuery代码如下:

[插图]

以上代码获取了<ul>元素里第2个<li>节点,并将它的文本内容“橘子”打印出来,效果如图3-3所示。

[插图]

图3-3 查找元素节点

2.查找属性节点

利用 jQuery 选择器查找到需要的元素之后,就可以使用 attr()方法来获取它的各种属性的值。attr()方法的参数可以是一个,也可以是两个。当参数是一个时,则是要查询的属性的名字,例如:

获取属性节点并打印出它的文本内容,jQuery代码如下:

[插图]

以上代码获取了<p>节点,并将它的title属性的值打印出来,效果如图3-4所示。

[插图]

图3-4 查找属性节点

3.2.2 创建节点

从第3.2.1小节可知,用jQuery选择器能够快捷而轻松地查找到文档中的某个特定的元素节点,然后可以用attr()方法来获取元素的各种属性的值。

真正的DOM操作并非这么简单。在DOM操作中,常常需要动态创建HTML内容,使文档在浏览器里的呈现效果发生变化,并且达到各种各样的人机交互的目的。

1.创建元素节点

例如要创建两个<li>元素节点,并且要把它们作为<ul>元素节点的子节点添加到DOM节点树上。完成这个任务需要两个步骤。
(1)创建两个<li>新元素。
(2)将这两个新元素插入文档中。

第(1)个步骤可以使用jQuery的工厂函数$()来完成,格式如下:

[插图]

$(html)方法会根据传入的HTML标记字符串,创建一个DOM对象,并将这个DOM对象包装成一个jQuery对象后返回。

首先创建两个<li>元素,jQuery代码如下:

[插图]

然后将这两个新元素插入文档中,可以使用jQuery中的append()等方法(将在第3.2.3小节进行介绍)。

jQuery代码如下:

[插图]

注意: (1)动态创建的新元素节点不会被自动添加到文档中,而是需要使用其他方法将其插入文档中。 (2)当创建单个元素时,要注意闭合标签和使用标准的XHTML格式。例如创建一个`

`元素,可以用$("<p/>")或者$("<p></p>"),但不要使用$("<p>")或者大写的$("<P/>")

运行代码后,新创建的<li>元素将被添加到网页中,因为暂时没有在它们内部添加任何文本,所以只能看到<li>元素默认的“· ”,如图3-5所示。

[插图]

图3-5 创建元素节点

2.创建文本节点

已经创建了两个<li>元素节点并把它们插入文档中了。此时需要为创建的元素节点添加文本内容。

jQuery代码如下:

[插图]

如以上代码所示,创建文本节点就是在创建元素节点时直接把文本内容写出来,然后使用append()等方法将它们添加到文档中就可以了。

创建的<li>节点显示到网页中的效果如图3-6所示。

[插图]

图3-6 创建文本节点
注意:无论$(html)中的HTML代码多么复杂,都可以使用相同的方式来创建。例如$("
  • 这是一个复杂的组合
  • ")

    3.创建属性节点

    创建属性节点与创建文本节点类似,也是直接在创建元素节点时一起创建。jQuery代码如下:

    [插图]

    运行代码后,效果如图3-7所示。

    [插图]

    图3-7 创建属性节点

    读者也许会发现图3-7与图3-6显示的效果没有什么区别,但事实上两者还是有差别的,可以通过Firebug工具来查看比较。

    注意:Firebug工具是FireFox浏览器的一个插件,它不仅能查看网页的文档结构,还能查看CSS、JavaScript等,是开发者必不可少的工具之一。具体介绍见附录Firebug。

    图3-6的网页内容在Firebug工具下显示的效果如图3-8所示。

    [插图]

    图3-8 新增的元素没有属性节点

    图3-7的网页内容在Firebug工具下显示的效果如图3-9所示。

    [插图]

    图3-9 新增的元素有title属性节点

    通过比较图3-8和图3-9对应的代码,发现图3-9的代码中最后两个<li>元素多了名为“title”的属性节点。由此可以判断,创建的元素的文本节点和属性节点都已经添加到网页中了。

    由此可见用jQuery来动态创建HTML元素是非常简单、方便和灵活的。

    3.2.3 插入节点

    动态创建 HTML 元素并没有实际用处,还需要将新创建的元素插入文档中。将新创建的节点插入文档最简单的办法是,让它成为这个文档的某个节点的子节点。前面使用了一个插入节点的方

    法append(),它会在元素内部追加新创建的内容。

    将新创建的节点插入某个文档的方法并非只有一种,在 jQuery 中还提供了其他几种插入节点的方法,如表3-1所示。读者可以根据实际需求灵活地做出多种选择。

    表3-1 插入节点的方法

    [插图]

    这些插入节点的方法不仅能将新创建的DOM元素插入到文档中,也能对原有的DOM元素进行移动。

    例如利用它们创建新元素并对其进行插入操作。

    jQuery代码如下:

    [插图]

    运行代码后,网页呈现效果如图3-10所示。

    [插图]

    图3-10 插入节点

    例如利用它们对原有的DOM元素进行移动。

    jQuery代码如下:

    [插图]

    运行代码后,网页呈现效果如图3-12所示。

    [插图]

    图3-12 移动之后

    3.2.4 删除节点

    如果文档中某一个元素多余,那么应将其删除。jQuery 提供了三种删除节点的方法,即remove(),detach()和empty()。

    1.remove()方法

    作用是从DOM中删除所有匹配的元素,传入的参数用于根据jQuery表达式来筛选元素。例如删除图3-11中<ul>节点中的第2个<li>元素节点,jQuery代码如下:

    [插图]

    图3-11 移动之前

    [插图]

    运行代码后效果如图3-13所示。

    [插图]

    图3-13 删除节点

    当某个节点用remove()方法删除后,该节点所包含的所有后代节点将同时被删除。这个方法的返回值是一个指向已被删除的节点的引用,因此可以在以后再使用这些元素。下面的jQuery 代码说明元素用remove()方法删除后,还是可以继续使用的。

    [插图]

    可以直接使用appendTo()方法的特性来简化以上代码,jQuery代码如下:

    [插图]

    [插图]

    图3-14 元素并未从jQuery对象中删除

    另外remove()方法也可以通过传递参数来选择性地删除元素,jQuery代码如下:

    [插图]

    运行代码后,效果如图3-15所示。

    [插图]

    图3-15 有选择性地删除元素

    在Firebug工具中查看源代码,如图3-16所示。

    [插图]

    图3-16 删除后的源文件

    2.detach()方法

    detach()和remove()一样,也是从DOM中去掉所有匹配的元素。但需要注意的是,这个方法不会把匹配的元素从 jQuery 对象中删除,因而可以在将来再使用这些匹配的元素。与 remove()不同的是,所有绑定的事件、附加的数据等都会保留下来。

    通过下面的例子,可以知道它与remove()方法的区别,jQuery代码如下:

    [插图]

    3.empty()方法

    严格来讲,empty()方法并不是删除节点,而是清空节点,它能清空元素中的所有后代节点。jQuery代码如下:

    [插图]

    当运行代码后,第2个<li>元素的内容被清空了,只剩下<li>标签默认的符号“·”,效果如图3-17所示。

    [插图]

    图3-17 清空元素

    在Firebug工具中查看源代码,如图3-18所示。

    [插图]

    图3-18 清空后的源文件

    3.2.5 复制节点

    复制节点也是常用的DOM操作之一,例如图3-19所示的某个购物网站的效果,用户不仅可以通过单击商品下方的“选择”按钮购买相应的产品,也可以通过鼠标拖动商品并将其放到购物车中。这个商品拖动功能就是用的复制节点,将用户选择的商品所处的节点元素复制一次,并将其跟随鼠标移动,从而达到以下购物效果。

    [插图]

    图3-19 购物网站的复制节点功能

    继续沿用之前的例子,如果单击<li>元素后需要再复制一个<li>元素,可以使用clone()方法来完成,jQuery代码如下:

    [插图]

    在页面中单击“菠萝”后,列表最下方出现新节点“菠萝”,效果如图3-20所示。

    [插图]

    图3-20 复制节点

    复制节点后,被复制的新元素并不具有任何行为。如果需要新元素也具有复制功能(本例中是单击事件),可以使用如下jQuery代码:

    [插图]

    在clone()方法中传递了一个参数true,它的含义是复制元素的同时复制元素中所绑定的事件。因此该元素的副本也同样具有复制功能(本例中是单击事件)。

    3.2.6 替换节点

    如果要替换某个节点,jQuery提供了相应的方法,即replaceWith()和replaceAll()。

    replaceWith()方法的作用是将所有匹配的元素都替换成指定的HTML或者DOM元素。例如要将网页中“<p title="选择你最喜欢的水果.">你最喜欢的水果是?</p>”替换成“<strong>你最不喜欢的水果是?</strong>”,可以使用如下jQuery代码:

    [插图]

    也可以使用jQuery中另一个方法replaceAll()来实现,该方法与replaceWith()方法的作用相同,只是颠倒了replaceWith()操作,可以使用如下jQuery代码实现同样的功能:

    [插图]

    这两句jQuery代码都会实现图3-21所示的效果。

    [插图]

    图3-21 替换节点
    注意:如果在替换之前,已经为元素绑定事件,替换后原先绑定的事件将会与被替换的元素一起消失,需要在新元素上重新绑定事件。

    3.2.7 包裹节点

    如果要将某个节点用其他标记包裹起来,jQuery提供了相应的方法,即wrap()。该方法对于需要在文档中插入额外的结构化标记非常有用,而且它不会破坏原始文档的语义。

    jQuery代码如下:

    [插图]

    得到的结果如下:

    [插图]

    在Firebug工具中查看源文件,效果如图3-22所示。

    [插图]

    图3-22 包裹节点源文件

    包裹节点操作还有其他两个方法,即wrapAll()和wrapInner()。

    1.wrapAll()方法

    该方法会将所有匹配的元素用一个元素来包裹。它不同于wrap()方法,wrap()方法是将所有的元素进行单独的包裹。

    为了使效果更突出,在网页中再加入一个<strong>元素。

    HTML代码如下:

    [插图]

    如果使用wrap()方法包裹<strong>元素,jQuery代码如下:

    [插图]

    将会得到如下结果:

    [插图]

    用Firebug工具查看源文件的效果如图3-23所示。

    [插图]

    图3-23 用wrap()方法包裹节点源文件

    使用wrapAll()方法包裹<strong>元素,jQuery代码如下:

    [插图]

    则会得到如下结果:

    [插图]

    [插图]

    用Firebug工具查看源文件的效果如图3-24所示。

    [插图]

    图3-24 用wrapAll()方法包裹节点源文件
    注意:如果被包裹的多个元素间有其它元素,其它元素会被放到包裹元素之后。

    2.wrapInner()方法

    该方法将每一个匹配的元素的子内容(包括文本节点)用其他结构化的标记包裹起来。例如可以使用它来包裹<strong>标签的子内容,jQuery代码如下:

    [插图]

    运行代码后,发现<strong>标签内的内容被一对<b>标签包裹了,结果如下:

    [插图]

    使用Firebug工具查看网页结构,显示效果如图3-25所示。

    [插图]

    图3-25 用wrapInner()方法包裹节点源文件

    3.2.8 属性操作

    在jQuery中,用attr()方法来获取和设置元素属性,removeAttr()方法来删除元素属性。

    1.获取属性和设置属性

    如果要获取<p>元素的属性title,那么只需要给attr()方法传递一个参数,即属性名称。

    jQuery代码如下:

    [插图]

    如果要设置<p>元素的属性title的值,也可以使用同一个方法,不同的是,需要传递两个参数即属性名称和对应的值。

    jQuery代码如下:

    [插图]

    如果需要一次性为同一个元素设置多个属性,可以使用下面的代码来实现:

    [插图]

    注意:jQuery 中的很多方法都是同一个函数实现获取(getter)和设置(setter)的,例如上面的attr()方法,既能设置元素属性的值,也能获取元素属性的值。类似的还有html()、text()、height()、width()、val()和css()等方法。

    2.删除属性

    在某些情况下,需要删除文档中某个元素的特定属性,可以使用 removeAttr()方法来完成该任务。

    如果需要删除<p>元素的title属性,可以使用下面的代码实现:

    [插图]

    运行代码后,<p>元素的title属性将被删除。此时<p>元素的HTML结构由

    [插图]

    变为

    [插图]

    注意:jQuery1.6中新增了prop()和removeProp(),分别用来获取在匹配的元素集中的第一个元素的属性值和为匹配的元素删除设置的属性。

    3.2.9 样式操作

    1.获取样式和设置样式

    HTML代码如下:

    [插图]

    在上面的代码中,class也是<p>元素的属性,因此获取class和设置class都可以使用attr()方法来完成。

    例如使用attr()方法来获取<p>元素的class,jQuery代码如下:

    [插图]

    也可以使用attr()方法来设置<p>元素的class,jQuery代码如下:

    [插图]

    运行代码后,上面的HTML代码将变为如下结构:

    [插图]

    上面的代码是将原来的class(myClass)替换为新的class(high)。如果此处需要的是“追加”效果,class属性变为“myClass high”,即myClass和high两种样式的叠加,那么我们可以使用addClass()方法。

    2.追加样式

    jQuery提供了专门的addClass()方法来追加样式。为了使例子更容易理解,首先在<style>标签里添加另一组样式:

    [插图]

    然后在网页中添加一个“追加class类”的按钮,按钮的事件代码如下:

    [插图]

    最后当单击“追加class类”按钮时,<p>元素样式就会变为斜体,而先前的红色字体也会变为蓝色,显示效果如图3-26所示。

    [插图]

    图3-26 addClass()方法

    在Firebug工具中查看class代码如图3-27所示。

    [插图]

    图3-27 class代码

    此时<p>元素同时拥有两个class值,即“high”和“another”。在CSS中有以下两条规定。
    (1)如果给一个元素添加了多个class值,那么就相当于合并了它们的样式。
    (2)如果有不同的class设定了同一样式属性,则后者覆盖前者。

    在上例中,相当于给<p>元素添加了如下样式:

    [插图]

    在以上的样式中,存在两个“color”属性,而后面的“color”属性会覆盖前面的“color”属性,因此最终的“color”属性的值为“blue”,而不是“red”。

    样式最终呈现为:

    [插图]

    追加样式和设置样式的区别如表3-2所示。

    表3-2 attr()和addClass()的区别

    [插图]

    3.移除样式

    在上面的例子中,为<p>元素追加了another样式。此时<p>元素的HTML代码变为:

    [插图]

    如果用户单击某个按钮时,要删除 class的某个值,那么可以使用与addClass()方法相反的removeClass()方法来完成,它的作用是从匹配的元素中删除全部或者指定的class。

    例如可以使用如下的jQuery代码来删除<p>元素中值为“high”的class:

    [插图]

    输出结果为:

    [插图]

    如果要把<p>元素的两个class都删除,就要使用两次removeClass()方法,代码如下:

    [插图]

    jQuery提供了更简单的方法。可以以空格的方式删除多个class名,jQuery代码如下:

    [插图]

    另外,还可以利用removeClass()方法的一个特性来完成同样的效果。当它不带参数时,就会将class的值全部删除,jQuery代码如下:

    [插图]

    此时,<p>元素的HTML结构为:

    [插图]

    4.切换样式

    在第2章的案例研究中介绍了一个方法,即toggle(),jQuery代码如下:

    [插图]

    toggle()方法此处的作用是交替执行代码③和代码④两个函数,如果元素原来是显示的,则隐藏它;如果元素原来是隐藏的,则显示它。此时,toggle()方法主要是控制行为上的重复切换。

    另外jQuery还提供了一个toggleClass()方法控制样式上的重复切换。如果类名存在则删除它,如果类名不存在则添加它。

    例如对<p>元素进行toggleClass()方法操作。

    jQuery代码如下:

    [插图]

    当单击“切换样式”按钮后,<p>元素的HTML代码由

    [插图]

    变为

    [插图]

    当再次单击“切换样式”按钮后,<p>元素的HTML代码又返回原来的状态:

    [插图]

    当不断单击“切换样式”按钮时,<p>元素的class的值就会在“myClass”和“myClass another”之间重复切换。

    5.判断是否含有某个样式

    hasClass()可以用来判断元素中是否含有某个class,如果有,则返回true,否则返回false。

    例如可以使用下面的代码来判断<p>元素中是否含有“another”的class:

    [插图]

    注意:这个方法是为了增强代码可读性而产生的。在jQuery内部实际上是调用了is()方法来完成这个功能的。该方法等价于如下代码:`$("p").is(".another")`;

    3.2.10 设置和获取HTML、文本和值

    1.html()方法

    此方法类似于JavaScript中的innerHTML属性,可以用来读取或者设置某个元素中的HTML内容。

    为了更清楚地展示效果,将<p>元素的HTML代码改成:

    [插图]

    然后用html()方法对<p>元素进行操作:

    [插图]

    运行代码后,效果如图3-28所示。

    [插图]

    图3-28 获取`

    `元素的HTML代码

    如果需要设置某元素的HTML 代码,那么也可以使用该方法,不过需要为它传递一个参数。例如要设置<p>元素的HTML代码,可以使用如下代码:

    [插图]

    注意:html()方法可以用于XHTML文档,但不能用于XML文档。

    2.text()方法

    此方法类似于JavaScript中的innerText属性,可以用来读取或者设置某个元素中的文本内容。继续使用以上的HTML代码:

    [插图]

    用text()方法对<p>元素进行操作:

    [插图]

    运行代码后,效果如图3-29所示:

    [插图]

    图3-29 获取`

    `元素的文本内容

    与 html()方法一样,如果需要为某元素设置文本内容,那么也需要传递一个参数。例如对<p>元素设置文本内容,代码如下:

    [插图]

    注意:(1)JavaScript中的innerText属性并不能在Firefox浏览器下运行,而jQuery的text()方法支持所有的浏览器。(2)text()方法对HTML文档和XML文档都有效。

    3.val()方法

    此方法类似于 JavaScript 中的value 属性,可以用来设置和获取元素的值。无论元素是文本框,下拉列表还是单选框,它都可以返回元素的值。如果元素为多选,则返回一个包含所有选择的值的数组。

    如图3-30所示,这是某网站的邮箱登录界面,默认状态下,邮箱地址文本框和邮箱密码框内分别有“请输入邮箱地址”和“请输入邮箱密码”的提示。

    [插图]

    图3-30 默认状态

    当将鼠标聚焦到邮箱地址文本框时,文本框内的“请输入邮箱地址”文字将被清空,效果如图3-31所示。

    [插图]

    图3-31 当地址文本框获得鼠标焦点时

    如果此时未在邮箱地址框中输入任何内容,而将鼠标焦点直接聚焦到密码输入框,则会发现密码框内的提示文字被清空了,同时邮箱地址输入框的提示也被还原了,效果如图3-32所示。

    [插图]

    图3-32 当地址框中未输入任何内容时,将鼠标焦点移动到密码框

    要实现以上例子展示的功能,可以使用val()方法。实现步骤如下。

    第1步:设计网页的基本结构。在页面中添加两个文本框,分别对两个文本框设置id,同时设置它们的默认值为“请输入邮箱地址”和“请输入邮箱密码”。

    HTML代码如下:

    [插图]

    呈现的网页效果如图3-33所示。

    [插图]

    图3-33 初始化效果

    第2步:对“地址框”进行操作。

    当地址框获取鼠标焦点时,如果地址框的值为“请输入邮箱地址”,则将地址框中的值清空。可以使用如下的jQuery代码:

    [插图]

    当地址框失去鼠标焦点时,如果地址框的值为空,则将地址框的值设置为“请输入邮箱地址”。可以使用如下的jQuery代码:

    [插图]

    注意:focus()方法相当于JavaScript中的onfocus()方法,作用是处理获得焦点时的事件。blur()方法相当于JavaScript中的onblur()方法,作用是处理失去焦点时的事件。

    第3步:对“密码框”进行操作,实现过程与“地址框”相同。

    此时,类似于YAHOO邮箱登录框的提示效果就完成了。完整代码如下:

    [插图]

    在该例子中,也可以使用表单元素的defaultValue属性来实现同样的功能,defaultValue属性包含该表单元素的初始值。代码如下:

    [插图]

    注意:this指向当前的文本框,“this.defaultValue”就是当前文本框的默认值。

    通过上面的例子可以发现val()方法不仅能设置元素的值,同时也能获取元素的值。另外,val()方法还有另外一个用处,就是它能使select(下拉列表框)、checkbox(多选框)和radio(单选框)相应的选项被选中,在表单操作中会经常用到。

    下面构建一个网页来演示val()方法的选中功能。

    HTML代码如下:

    [插图]

    运行代码后,显示效果如图3-34所示。

    [插图]

    图3-34 初始化

    该网页中一些元素是默认选中的,可以通过 val()方法来改变它们的选中项。如果要使第1个下拉框的第2项被选中,可以用以下jQuery代码实现:

    [插图]

    如果要使下拉列表的第2项和第3项被选中,可以用以下jQuery代码实现:

    [插图]

    依照上面类似的写法,下面的代码可以使多选框和单选框被选中,jQuery代码如下:

    [插图]

    运行代码后,显示效果如图3-35所示。

    [插图]

    图3-35 设置多选框和单选框
    注意:在上面这个例子中,可以使用val()方法,也可以使用attr()方法来实现同样的功能。

    [插图]

    3.2.11 遍历节点

    1.children()方法

    该方法用于取得匹配元素的子元素集合。

    此处使用本章开头所画的那颗DOM树的结构,如图3-36所示。

    [插图]

    图3-36 DOM树

    根据DOM树的结构,可以知道各个元素之间的关系以及它们子节点的个数。<body>元素下有<p><ul>两个子元素,<p>元素没有子元素,<ul>元素有3个<li>子元素。

    下面使用children()方法来获取匹配元素的所有子元素的个数。

    jQuery代码如下:

    [插图]

    注意:children()方法只考虑子元素而不考虑其他后代元素。

    2.next()方法

    该方法用于取得匹配元素后面紧邻的同辈元素。

    从 DOM 树的结构中可以知道<p>元素的下一个同辈节点是<ul>,因此可以通过next()方法来获取<ul>元素,代码如下:

    [插图]

    得到的结果将是:

    [插图]

    3.prev()方法

    该方法用于取得匹配元素前面紧邻的同辈元素。

    从DOM树的结构中可以知道<ul>元素的上一个同辈节点是<p>,因此可以通过prev()方法来获取<p>元素,代码如下:

    [插图]

    得到的结果将是:

    [插图]

    4.siblings()方法

    该方法用于取得匹配元素前后所有的同辈元素。

    在第1章导航栏的例子中有段代码如下:

    [插图]

    上面的代码中就用到了 siblings()方法,当时是为了获取匹配元素的兄弟节点,即获取匹配元素的同辈元素。

    以DOM树的结构为例。<ul>元素和<p>元素互为同辈元素,<ul>元素下的3个<li>元素也互为同辈元素。如果要获取<p>元素的同辈元素,则可以使用如下代码:

    [插图]

    得到的结果将是:

    [插图]

    5.closest()

    该方法用于取得最近的匹配元素。首先检查当前元素是否匹配,如果匹配则直接返回元素本身。如果不匹配则向上查找父元素,逐级向上直到找到匹配选择器的元素。如果什么都没找到则返回一个空的jQuery对象。

    比如,给点击的目标元素的最近的li元素添加颜色,可以使用如下代码:

    [插图]

    6.parent(),parents()与closest()的区别

    parent(),parents()与closest()方法两两之间有类似又有不同,在此简短的区分一下这三个方法。如表3-3所示。读者可以根据实际需求灵活地选择使用哪个方法。

    表3-3 parent(),parents()与closest()的区别

    [插图]

    除此之外,在 jQuery 中还有很多遍历节点的方法,例如 find()、filter()、nextAll()和prevAll()等,此处不再赘述,读者可以查看附录的jQuery 速查表文档。值得注意的是,这些遍历 DOM 方法有一个共同点,都可以使用jQuery表达式作为它们的参数来筛选元素。

    3.2.12 CSS-DOM操作

    CSS-DOM技术简单来说就是读取和设置style对象的各种属性。style属性很有用,但最大不足是无法通过它来提取到通过外部CSS设置的样式信息,然而在jQuery中,这些都是非常的简单。

    可以直接利用css()方法获取元素的样式属性,jQuery代码如下:

    [插图]

    无论color属性是外部CSS导入,还是直接拼接在HTML元素里(内联),css()方法都可以获取到属性style里的其他属性的值。

    也可以直接利用css()方法设置某个元素的单个样式,例如:

    [插图]

    与attr()方法一样,css()方法也可以同时设置多个样式属性,代码如下:

    [插图]

    注意:(1)如果值是数字,将会被自动转化为像素值。(2)在css()方法中,如果属性中带有“-”符号,例如font-size和background-color属性,如果在设置这些属性的值的时候不带引号,那么就要用驼峰式写法,例如:`$("p").css({ fontSize : "30px" , backgroundColor : "#888888" })`如果带上了引号,既可以写成“font-size”,也可以写成“fontSize”。总之建议大家加上引号,养成良好的习惯。

    对透明度的设置,可以直接使用opacity属性,jQuery已经处理好了兼容性的问题,如下代码所示,将<p>元素的透明度设置为半透明:

    [插图]

    如果需要获取某个元素的height属性,则可以通过如下jQuery代码实现:

    [插图]

    在jQuery中还有另外一种方法也可以获取元素的高度,即height()。它的作用是取得匹配元素当前计算的高度值(px)。jQuery代码如下:

    [插图]

    height()方法也能用来设置元素的高度,如果传递的值是一个数字,则默认单位为px。如果要用其他单位(例如em),则必须传递一个字符串。jQuery代码如下:

    [插图]

    注意:(1)在jQuery 1.2版本以后的height()方法可以用来获取window和document的高度。(2)两者的区别是:css()方法获取的高度值与样式的设置有关,可能会得到"auto",也可能得到"10px"之类的字符串;而 height()方法获取的高度值则是元素在页面中的实际高度,与样式的设置无关,并且不带单位。

    与height()方法对应的还有一个width()方法,它可以取得匹配元素的宽度值(px)。

    [插图]

    同样,width()方法也能用来设置元素的宽度。

    [插图]

    此外,在CSS-DOM中,关于元素定位有以下几个经常使用的方法。

    1.offset()方法

    它的作用是获取元素在当前视窗的相对偏移,其中返回的对象包含两个属性,即top和left,它只对可见元素有效。例如用它来获取<p>元素的的偏移量,jQuery代码如下:

    [插图]

    2.position()方法

    它的作用是获取元素相对于最近的一个position样式属性设置为relative或者absolute的祖父节点的相对偏移,与 offset()一样,它返回的对象也包括两个属性,即 top和left。jQuery代码如下:

    [插图]

    3.scrollTop()方法和scrollLeft()方法

    这两个方法的作用分别是获取元素的滚动条距顶端的距离和距左侧的距离。例如使用下面的代码获取<p>元素的滚动条距离:

    [插图]

    另外,可以为这两个方法指定一个参数,控制元素的滚动条滚动到指定位置。例如使用如下代码控制元素内的滚动条滚动到距顶端300和距左侧300的位置:

    [插图]

    至此,已经将jQuery中常用的DOM操作(包括DOM Core,HTML-DOM和CSS-DOM)都已经介绍完毕。以下将结合这些方法,研究一个融合了DOM操作的实例。

    2.8 小结

    本章详细讲解了 jQuery 中的各种类型的选择器。选择器是行为与文档内容之间连接的纽带,选择器的最终目的就是能够轻松地找到文档中的元素。

    在本章的开始列举了3个用传统JavaScript方法写的简单例子,然后介绍了jQuery选择器,并用所学的jQuery 选择器以及隐式迭代的特性将例子进行改写。此外还讲解了选择器中的一些注意事项,希望能引起初学者的注意。最后以某网站上一个品牌列表作为例子,加深读者对 jQuery 选择器用法的理解。

    2.7 其他选择器

    2.7.1 jQuery提供的选择器的扩展

    虽然 jQuery 提供了许多实用的选择器,但还是有可能不能满足各种多变的业务需要,不过jQuery选择器是可以进一步扩展的。

    1.MoreSelectors for jQuery

    这是一个jQuery的插件,用于增加更多的选择器,例如.color可以匹配颜色,:colIndex可以匹配表格中的列,:focus可以匹配获取焦点的元素等。

    插件地址:http://plugins.jquery.com/project/moreSelectors

    2.Basic XPath

    这个插件可以让用户使用基本的XPath。jQuery最开始支持XPath选择器,但由于使用人数不多,且降低了选择器匹配的效率,因此在1.2以后的版本中取消了默认对XPath选择器的支持,改为通过插件来实现。

    插件地址:http://plugins.jquery.com/project/xpath

    2.7.2 其他使用CSS选择器的方法

    除了 jQuery 提供了强大的选择器支持外,也有其他一些 JavaScript 脚本也提供了此类纯粹的CSS选择器的支持。

    1.document.getElementsBySelector()

    早在2003年,Simon Willison就编写了该脚本,它的作用是通过选择器来获取文档元素。读者可以通过以下代码获取元素。

    [插图]

    该脚本最新版本为0.4版,更新日期为2003年3月25日。

    发布地址:http://simonwillison.net/2003/Mar/25/getElementsBySelector/

    2.cssQuery()

    这是Dean Edwards编写的一款利用CSS选择器查找元素的脚本。支持所有CSS1、CSS2以及部分CSS3选择器,jQuery的选择器其实是源自于此,它支持一些jQuery尚不支持的选择器,例如 E:link、E:nth-last-child(n)、E:root、E:lang(fr)、E:target和E[foo|=”bar”]等。语法结构如下:

    [插图]

    该脚本最新版本为2.0.2版,更新日期为2005年9月10日。

    官方网站:http://dean.edwards.name/my/cssQuery/

    3.querySelectorAll()

    这不是一个脚本库,而是W3C在Selectors API草案中提到的方法,该草案的最新版本是在2007年12月21日发布的。此方法也是用于实现通过CSS选择器来获取元素的。IE 8的Beta 2中已经率先实现了此方法。相信其他几大浏览器也很快就能实现此方法。

    JQuery的作者 John Resig 也表示将会利用 querySelectorAll()这个浏览器原生的方法来重构jQuery的选择器,同时增加一些jQuery扩展的选择器,届时jQuery选择器的执行效率也将大大提高。

    W3C Selectors API:http://www.w3.org/TR/selectors-api/

    2.6 案例研究—某网站品牌列表的效果

    以下是某网站上的一个品牌列表的展示效果,用户进入该页面时,品牌列表默认是精简显示的(即不完整的品牌列表),如图2-6所示。

    用户可以单击商品列表下方的“显示全部品牌”按钮来显示全部的品牌。

    单击“显示全部品牌”按钮的同时,列表会将推荐的品牌的名字高亮显示,按钮里的文字也换成了“精简显示品牌”,如图2-7所示。

    [插图]

    图2-6 品牌展示列表(精简)

    [插图]

    图2-7 品牌展示列表(全部)

    再次单击“精简显示品牌”按钮,即又回到图2-6所示的页面。

    为了实现这个例子,首先需要设计它的HTML结构。HTML代码如下:

    [插图]

    然后为上面的HTML代码添加CSS样式。页面初始化的效果如图2-8所示。

    接下来为这个页面添加一些交互效果,要做的工作有以下几项。

    [插图]

    图2-8 品牌展示列表(精简)

    (1)从第7条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。
    (2)当用户单击“显示全部品牌”按钮时,将执行以下操作。
    ① 显示隐藏的品牌。
    ② “显示全部品牌”按钮文本切换成“精简显示品牌”。
    ③ 高亮推荐品牌。

    (3)当用户单击“精简显示品牌”按钮时,将执行以下操作。
    ① 从第7条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。
    ② “精简显示品牌”按钮文本切换成“显示全部品牌”。
    ③ 去掉高亮显示的推荐品牌。

    (4)循环进行第(2)步和第(3)步。
    下面逐步来完成以上的效果。

    (1)从第7条开始隐藏后面的品牌(最后一条“其它品牌相机”除外)。

    [插图]

    $('ul li:gt(5):not(:last)')的意思是先获取<ul>元素下索引值大于5的<li>元素的集合元素,然后去掉集合元素中的最后一个元素。这样,即可将从第7条开始至倒数第2条的所有品牌都获取到。最后通过hide()方法隐藏这些元素。

    (2)当用户单击“显示全部品牌”按钮时,执行以下操作。
    首先获取到按钮,代码如下:

    [插图]

    然后给按钮添加事件,使用show()方法把隐藏的品牌列表显示出来,代码如下:

    [插图]

    由于给超链接添加onclick事件,因此需要使用“return false”语句让浏览器认为用户没有单击该超链接,从而阻止该超链接跳转。

    之后,需要将“显示全部品牌”按钮文本切换成“精简显示品牌”,代码如下:

    [插图]

    这里完成了两步操作,即把按钮的背景图片换成向上的图片,同时也改变了按钮文本内容,将其替换成“精简显示品牌”。

    接下来需要高亮推荐品牌,代码如下:

    [插图]

    使用filter()方法筛选出符合要求的品牌,然后为它们添加promoted样式。在这里推荐了3个品牌,即佳能、尼康和奥林巴斯。

    此时,完成的jQuery代码如下:

    [插图]

    运行上面的代码,单击“显示全部品牌”按钮后,显示图2-9所示的效果,此时已经能够正常显示全部品牌了。

    [插图]

    图2-9 当按钮被单击后
    注意:上面代码中用到的几个jQuery方法的意思如下:
    • show():显示隐藏的匹配元素。
    • css(name,value):给元素设置样式。
    • text(string):设置所有匹配元素的文本内容。
    • filter(expr):筛选出与指定表达式匹配的元素集合,其中expr可以是多个选择器的组合。注意区分它和find()方法。find()会在元素内寻找匹配元素,而filter()则是筛选元素。一个是对它的子集操作,一个是对自身集合元素进行筛选。
    • addClass(class):为匹配的元素添加指定的类名。

    (3)当用户单击“精简显示品牌”按钮时,将执行以下操作。

    由于用户单击的是同一个按钮,因此事件仍然是在刚才的按钮元素上。要将切换两种状态的效果在一个按钮上进行,可以通过判断元素的显示或者隐藏来达到目的,代码结构如下:

    [插图]

    代码②就是第(2)步的内容,接下来只需要完成代码①的内容即可。

    在jQuery中,与show()方法相反的是hide()方法,因此可以使用hide()方法将品牌隐藏起来,代码如下:

    [插图]

    然后将“精简显示品牌”按钮文本切换成“显示全部品牌”,同时按钮图片换成向下的图片,这一步与前面类似,只不过是图片路径和文本内容不同而已,代码如下:

    [插图]

    接下来需要去掉所有品牌的高亮显示状态,此时可以使用 removeClass()方法来完成,代码如下:

    [插图]

    它将去掉所有<li>元素上的“promoted”样式,即去掉了品牌的高亮状态。

    注意:removeClass(class)的功能和addClass(class)的功能正好相反。addClass(class)的功能是为匹配的元素添加指定的类,而removeClass(class)则是从匹配的元素中删除指定的类。

    至此完成代码①。

    最后通过判断元素是否显示来分别执行代码①和代码②,代码如下:

    [插图]

    之后即可将代码①和代码②插入相应的位置。jQuery代码如下:

    [插图]

    至此任务完成,完整的jQuery代码如下:

    [插图]

    运行代码后,单击按钮,品牌列表会在“全部”和“精简”两种效果之间循环切换,显示效果如图2-10和图2-11所示。

    [插图]

    图2-10 精简模式

    [插图]

    图2-11 全部模式

    在 jQuery 中有一个方法更适合上面的情况,它能给一个按钮添加一组交互事件,而不需要像上例一样去判断,上例的代码如下:

    [插图]

    如果改成toggle()方法,代码则可以直接写成以下形式:

    [插图]

    当单击按钮后,脚本会对代码③和代码④进行交替处理。

    jQuery还提供了很多简单易用的方法,上面讲解的toggle()方法只是其中的一种,这些方法将在后面的章节中进行详细介绍。

    注意:在本例中,如果用户禁用了JavaScript的功能,品牌列表仍然能够完全显示,当用户单击“显示全部品牌”按钮的时候,会跳转到 more.html页面来显示品牌列表。作为一名专业的开发者,必须要考虑到禁用或者不支持 JavaScript的浏览器(用户代理)。另外,这点对于搜索引擎优化也特别有帮助,毕竟当前的搜索引擎爬虫基本都不支持JavaScript。

    2.5 选择器中的一些注意事项

    2.5.1 选择器中含有特殊符号的注意事项

    1.选择器中含有“· ”、“#”、“(”或“]”等特殊字符

    根据W3C的规定,属性值中是不能含有这些特殊字符的,但在实际项目中偶尔会遇到表达式中含有“#”和“.”等特殊字符,如果按照普通的方式去处理出来的话就会出错。解决此类错误的方法是使用转义符转义。

    HTML代码如下:

    1
    2
    <div id="id#b">bb</div>
    <div id="id[1]">cc</div>

    如果按照普通的方式来获取,例如:

    1
    2
    $("#id#b").css("background","#bbffaa");
    $("#id[1]").css("background","#bbffaa");

    以上代码不能正确获取到元素,正确的写法如下:

    1
    2
    $("#id\\#b").css("background", "#bbffaa"); //转义特殊字符“#”
    $("#id\\[1\\]").css("background", "#FF6500"); //转义特殊字符“[]”

    2.属性选择器的@符号问题

    在jQuery升级版本过程中,jQuery在1.3.1版本中彻底放弃了1.1.0版本遗留下的@符号,假如你使用1.3.1以上的版本,那么你不需要在属性前添加@符号,比如:

    1
    $("div[@title='test']"];

    正确的写法是去掉@符号,比如:

    1
    $("div[title='test']"];
    注意:如果你的项目中已使用较早的jQuery代码和插件,若把jQuery升级到最新后,出现代码报错或不能运行,那么很有可能是因为代码中使用了属性选择器的@符号而引起的。

    2.5.2 选择器中含有空格的注意事项

    选择器中的空格也是不容忽视的,多一个空格或少一个空格也许会得到截然不同的结果。

    看下面这个例子,它的HTML代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="test">
    <div style="display:none;">aa</div>
    <div style="display:none;">bb</div>
    <div style="display:none;">cc</div>
    <div class="test" style="display:none;">dd</div>
    </div>
    <div class="test" style="display:none;">ee</div>
    <div class="test" style="display:none;">ff</div>

    使用如下的jQuery选择器分别获取它们。

    1
    2
    3
    4
    5
    6
    var $t_a = $('.test :hidden'); //带空格的JQuery选择器
    var $t_b = $('.test:hidden'); //不带空格的JQuery选择器
    var len_a = $t_a.length;
    var len_b = $t_b.length;
    alert("$('.test :hidden') = " + len_a); //输出 4
    alert("$('.test:hidden') = " + len_b); //输出 3

    之所以会出现不同的结果,是因为后代选择器与过滤选择器的不同。

    1
    var $t_a = $('.test :hidden'); //带空格的

    以上代码是选取class为“test”的元素里面的隐藏元素。而代码:

    1
    var $t_b = $('.test:hidden'); //不带空格的

    则是选取隐藏的class为“test”的元素。

    2.4 应用jQuery改写示例

    在本章开头部分,使用传统的JavaScript方法编写了3个简单的例子。

    例子1:给网页中所有的<p>元素添加onclick事件。
    例子2:使一个特定的表格隔行变色。
    例子3:对多选框进行操作,输出选中的多选框的个数。

    下面利用刚学会的jQuery选择器以及隐式迭代的特性来重写这3个例子。

    使用jQuery选择器重写例子1,代码如下。

    1
    2
    3
    $("p").click(function(){ //获取页面中的所有p元素,给每一个p元素添加单击事件
    //doing something
    })

    使用jQuery选择器重写例子2,代码如下:

    1
    2
    3
    4
    5
    6
    /*
    *获取id为tb的元素,然后寻找它下面的tbody标签,再寻找tbody下索引值是偶数的tr元素,
    * 改变它的背景色。
    *css("property","value"):用来设置jQuery对象的样式
    */
    $("#tb tbody tr:even").css("backgroundColor", "#888");

    使用jQuery选择器重写例子3,代码如下:

    1
    2
    3
    4
    5
    $("#btn").click(function() {
    //先使用属性选择器,然后用表单对象属性过滤,最后获取jQuery对象的长度
    var items = $("input[name='check']:checked");
    alert("选中的个数为:" + items.length);
    });

    很快就改完了,仅仅使用了几个简单的jQuery 选择器,而且它们的运行效果与改写前是完全相同的。

    2.3 jQuery选择器

    在正式学习jQuery选择器之前,先看几组用传统的JavaScript方法获取页面中的元素,然后给元素添加行为事件的例子。

    例子1:给网页中的所有<p>元素添加onclick事件。

    HTML代码如下:

    1
    2
    <p>测试1</p>
    <p>测试2</p>

    要做的工作有以下几项。
    (1)获取所有的<p>元素。
    (2)对<p>元素进行循环(因为获取的是数组对象)。
    (3)给每个<p>元素添加行为事件。

    JavaScript代码如下:

    1
    2
    3
    4
    5
    6
    var items = document.getElementsByTagName("p");//获取网页中所有的p元素
    for(var i=0;i < items.length;i++){ //由于获取的是数组对象,因此需要把它循环出来
    items[i].onclick = function(){ //给每个对象添加onclick事件
    //doing something
    }
    }

    例子2:使一个特定的表格隔行变色。

    HTML代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <table id="tb">
    <tbody>
    <tr><td>第一行</td><td>第一行</td></tr>
    <tr><td>第二行</td><td>第二行</td></tr>
    <tr><td>第三行</td><td>第三行</td></tr>
    <tr><td>第四行</td><td>第四行</td></tr>
    <tr><td>第五行</td><td>第五行</td></tr>
    <tr><td>第六行</td><td>第六行</td></tr>
    </tbody>
    </table>

    要做的工作有以下几项。
    (1)根据表格id获取表格。
    (2)在表格内获取<tbody>元素。
    (3)在<tbody>元素下获取<tr>元素。
    (4)循环输出获取的<tr>元素。
    (5)对<tr>元素的索引值除以2并取模,然后根据奇偶设置不同的背景色。

    JavaScript代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    var item = document.getElementById("tb"); //获取id为tb的元素(table)
    var tbody = item.getElementsByTagName("tbody")[0]; //获取表格的第1个tbody元素
    var trs = tbody.getElementsByTagName("tr"); //获取tbody元素下的所有tr元素
    for (var i = 0; i < trs.length; i++) { //循环tr元素
    if (i % 2 == 0) { //取模(取余数。例如0%2==0,1%2==1,2%2==0,3%2==1)
    trs[i].style.backgroundColor = "#888"; //改变符合条件的tr元素的背景色
    }
    }

    例子3:对多选框进行操作,输出选中的多选框的个数。

    HTML代码如下:

    1
    2
    3
    4
    <input type="checkbox" value="1" name="check" checked="checked"/>
    <input type="checkbox" value="2" name="check"/>
    <input type="checkbox" value="3" name="check" checked="checked"/>
    <input type="button" value="你选中的个数" id="btn"/>

    要做的工作有以下几项。
    (1)新建一个空数组。
    (2)获取所有name为“check”的多选框。
    (3)循环判断多选框是否被选中,如果被选中则添加到数组里。
    (4)获取输出按钮,然后为按钮添加onclick事件,输出数组的长度即可。

    JavaScript代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //获取id为btn的元素(button)
    var btn = document.getElementById("btn");
    //给元素添加onclick事件
    btn.onclick = function () {
    //创建一个数组对象
    var arrays = new Array();
    //获取name为check的一组元素(checkbox)
    var items = document.getElementsByName("check");

    //循环这组数据
    for (i = 0; i < items.length; i++) {
    //判断是否选中
    if (items[i].checked) {
    //把符合条件的数据添加到数组中
    arrays.push(items[i].value);
    //push()是JavaScript数组中的方法
    }
    }
    alert("选中的个数为:" + arrays.length)
    }

    上面的几个例子都是用传统的JavaScript 方法进行操作,中间使用了 getElementById()、getElementsByTagName()和getElementsByName()等方法,然后动态地给元素添加行为或者样式。这些虽然都是JavaScript中最简单的操作,但不断重复使用getElementById()和getElementsByTagName()等冗长而难记的名称,使越来越多的开发人员开始厌倦这种枯燥的写法,并且有时候为了获取网页中的某个元素,需要编写很多的getElementById()和getElementsByTagName()方法。然而在 jQuery中,类似的这些操作则非常简洁。

    下面学习如何使用jQuery获取这些元素。

    jQuery选择器分为基本选择器、层次选择器、过滤选择器和表单选择器。在下面的章节中将分别用不同的选择器来查找 HTML 代码中的元素并对其进行简单的操作。为了能更清晰、直观地讲解选择器,首先需要设计一个简单的页面,里面包含各种<div>元素和<span>元素,然后使用jQuery选择器来匹配元素并调整它们的样式。

    新建一个空白页面,输入以下HTML代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <div class="one" id="one">
    id为one,class为one的div
    <div class="mini">class为mini</div>
    </div>
    <div class="one" id="two" title="test">
    id为two,class为one,title为test的div.
    <div class="mini" title="other">class为mini,title为other</div>
    <div class="mini" title="test">class为mini,title为test</div>
    </div>
    <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
    <div class="mini"></div>
    </div>
    <div class="one">
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
    <div class="mini">class为mini</div>
    <div class="mini" title="tesst">class为mini,title为tesst</div>
    </div>
    <div style="display:none;" class="none">
    style的display为"none"的div
    </div>
    <div class="hide">class为"hide"的div</div>
    <div>
    包含input的type为"hidden"的div<input type="hidden" size="8" />
    </div>
    <span id="mover">正在执行动画的span元素.</span>

    然后用CSS对这些元素进行初始化大小和背景颜色的设置,CSS代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    div,span,p {
    width: 140px;
    height: 140px;
    margin: 5px;
    background: #aaa;
    border: #000 1px solid;
    float: left;
    font-size: 17px;
    font-family: Verdana;
    }
    div.mini {
    width: 55px;
    height: 55px;
    background-color: #aaa;
    font-size: 12px;
    }
    div.hide {
    display: none;
    }

    根据以上HTML+CSS代码,可以生成图2-2所示的页面效果。

    image-20211215155456971

    图2-2 初始状态

    2.3.1 基本选择器

    基本选择器是jQuery中最常用的选择器,也是最简单的选择器,它通过元素id、class和标签名等来查找DOM元素。在网页中,每个id名称只能使用一次,class允许重复使用。基本选择器的介绍说明如表2-2所示。

    表2-2 基本选择器

    epub_731606_46

    选择器 描述 返回 示例
    #id 根据给定的id匹配一个元素 单个元素 $("")选取id为test的元素
    .class 根据给定的类名匹配元素 集合元素 $("")选取所有class为test的元素
    element 根据给定的元素名匹配元素 集合元素 $("")选取所有的<p>元素
    selector1,selector2,...,selectorN 将每一个选择器匹配到的元素合并后一起返回 集合元素 $("div,span,p.myClass")选取所有<div>,span和拥有class为myClass的<p>标签的一组元素

    可以使用这些基本选择器来完成绝大多数的工作。下面用它们来匹配刚才 HTML代码中的<div><span>等元素并进行操作(改变背景色),示例如表2-3所示。

    表2-3 基本选择器示例
    功能 代码 执行后
    改变id为one的元素的背景色 $("#one").css("background","#bbffaa"); image-20211215155942007
    改变class为mini的所有元素的背景色 $(".mini").css("background","#bbffaa"); image-20211215161918372
    改变元素名是<div>的所有元素的背景色 $("div").css("background","#bbffaa"); image-20211215162721046
    改变所有元素的背景色 $("*").css("background","#bbffaa"); image-20211215162047746
    改变所有的span元素和id为two的元素的背景色 $("span,#two").css("background","#bbffaa"); image-20211215162116977

    2.3.2 层次选择器

    如果想通过DOM元素之间的层次关系来获取特定元素,例如后代元素、子元素、相邻元素和同辈元素等,那么层次选择器是一个非常好的选择。层次选择器的介绍说明如表2-4所示。

    表2-4 层次选择器
    选择器 描述 返回 示例
    $("ancestor descendant") 选取ancestor元素里的所有descendant(后代)元素 集合元素 $("div span")选取<div>里的所有的<span>元素
    $("parent>child") 选取parent元素下的child(子)元素,与$("ancestor descendant")有区别,$("ancestor descendant")选择的后代元素 集合元素 $("div>span")选取<div>元素下的元素名是<span>的子元素
    $("prev+next") 选取紧接在prev元素后的next元素 集合元素 $(".one+div")选取classone的下一个<div>同辈元素。
    $("prev~siblings") 选取prev元素之后的所有siblings元素 集合元素 $("#two~div")选取idtwo的元素后面的所有<div>同辈元素

    继续沿用刚才例子中的HTML和CSS 代码,然后用层次选择器来对网页中的<div><span>等元素进行操作,示例如表2-5所示。

    表2-5 层次选择器示例
    功能 代码 执行后
    改变<body>内所有<div>的背景色 $("body div").css("background","#bbffaa"); image-20211215185504190
    改变<body>内子<div>元素的背景色 $("body>div").css("background","#bbffaa"); image-20211215185748518
    改变classone的下一个<div>同辈元素的背景色 $(".one+div").css("background","#bbffaa"); image-20211215185911800
    改变idtwo的元素后面的所有<div>同辈元素的背景色 $("#two~div").css("background","#bbffaa"); image-20211215190808240

    在层次选择器中,第1个和第2个选择器比较常用,而后面两个因为在jQuery里可以用更加简单的方法代替,所以使用的几率相对少些。

    可以使用next()方法来代替$('prev + next')选择器,如表2-6所示。

    表2-6 $('prev + next')选择器与next()方法的等价关系
    选择器 方法
    等价关系 $(".one+div") $(".one").next("div")

    可以使用nextAll()方法来代替$('prev~siblings')选择器,如表2-7所示。

    表2-7 $('prev~iblings')选择器与nextAll()方法的等价关系
    选择器 方法
    等价关系 $("#prev~div") $("#prev").nextAll("div")

    在此我将后面要讲解的siblings()方法拿出来与$('prev~siblings')选择器进行比较。$("#prev~div")选择器只能选择“prev”元素后面的同辈<div>元素。而siblings()方法与前后位置无关,只要是同辈节点就都能匹配。

    1
    2
    3
    4
    5
    6
    //选取#prev之后的所有同辈div元素
    $("#prev~div").css("background","#bbffaa");
    //同上
    $("#prev").nextAll("div").css("background","#bbffaa");
    //选取#prev所有的同辈div元素,无论前后位置
    $("#prev").siblings("div").css("background","#bbffaa");

    例如:

    1
    2
    3
    4
    //选取#two之后的所有同辈div元素
    $("#two~div").css("background","#bbffaa");
    //同上
    $("#two").nextAll("div").css("background","#bbffaa");

    效果为:
    image-20211215200300198
    而:

    1
    2
    //选取#two所有的同辈div元素,无论前后位置
    $("#two").siblings("div").css("background","#bbffaa");

    效果为:
    image-20211215200308529

    2.3.3 过滤选择器

    过滤选择器主要是通过特定的过滤规则来筛选出所需的DOM元素,过滤规则与CSS中的伪类选择器语法相同,即选择器都以一个冒号(:)开头。按照不同的过滤规则,过滤选择器可以分为基本过滤、内容过滤、可见性过滤、属性过滤、子元素过滤和表单对象属性过滤选择器。

    1.基本过滤选择器

    表2-8 基本过滤选择器

    epub_731606_52

    选择器 描述 返回 示例
    :first 选取第一个元素 单个元素 $("div:first")选取所有<div>元素的第1个<div>元素
    :last 选取最后一个元素 单个元素 $("div:last")选取所有<div>元素中最后一个<div>元素
    :not(selector) 去除所有与给定选择器匹配的元素 集合元素 $("input:not(.myClass)")选取class不是myClass<input>元素
    :even 选取索引是偶数的所有元素,索引从0开始 集合元素 $("input:even")选取索引是偶数的<input>元素
    :odd 选取索引是奇数的所有元素,索引从0开始 集合元素 $("input:odd")选取索引是奇数的<input>元素
    :eq(index) 选取索引等于index的元素(index从0开始) 单个元素 $("input:eq(1)")选取索引等于1的<input>元素
    :gt(index) 选取索引大于index的元素(index从0开始) 集合元素 $("input:gt(1)")选取索引大于1的<input>元素,(注:大于1,而不包括1)
    :lt(index) 选取索引小于index的元素(index从0开始) 集合元素 $("input:lt(1)")选取索引小于1的<input>元素,(注:小于1,而不包括1)
    :header 选取所有的标题元素,例如<h1><h2><h3>等等 集合元素 $(":header")选取网页中所有的<h1><h2><h3>,…..
    :animated 选取当前正在执行动画的所有元素 集合元素 $("div:animated")选取正在执行动画的<div>元素。
    :focus 选取当前正在获取焦点的元素 集合元素 $(":focus")选取当前获取焦点的元素

    接下来,使用这些基本过滤选择器来对网页中的<div><span>等元素进行操作,示例如表2-9所示。

    表2-9 基本过滤选择器示例

    epub_731606_53

    功能 代码 执行后
    改变第一个<div>元素的背景色 $("div:first").css("background","#bbffaa"); image-20211216090106901
    改变最后一个<div>元素的背景色 $("div:last").css("background","#bbffaa"); image-20211216090229258
    续表

    epub_731606_54

    功能 代码 执行后
    改变class不为one<div>元素的背景色 $("div:not(.one)").css("background","#bbffaa"); image-20211216090542768
    改变索引值为偶数的<div>元素的背景色 $("div:even").css("background","#bbffaa"); image-20211216090659831
    改变索引值为奇数的<div>元素的背景色 $("div:odd").css("background","#bbffaa"); image-20211216091209172
    改变索引值等于3的<div>元素的背景色 $("div:eq(3)").css("background","#bbffaa"); image-20211216091308548
    改变索引值大于3的<div>元素的背景色 $("div:gt(3)").css("background","#bbffaa"); image-20211216091416022
    续表

    epub_731606_55

    功能 代码 执行后
    改变索引值小于3的<div>元素的背景色 $("div:lt(3)").css("background","#bbffaa"); image-20211216091811950
    改变所有的标题元素,例如<h1><h2><h3>,…这些元素的背景色 $(":header").css("background","#bbffaa"); image-20211216092505907
    改变当前正在执行动画的元素的背景色 $(":animated").css("background","#bbffaa"); image-20211216094031802
    改变当前获取焦点的元素的背景色 $(":focus").css("background","#bbffaa"); 插图

    执行动画的测试方法如下:
    HTML:同上
    JS:

    1
    2
    3
    4
    5
    6
    7
    for(i=0;i<10;i++){
    // 执行动画
    $("#mover").hide(1000*3);
    $("#mover").show(1000*3);
    }
    // 改变当前正在执行动画的元素的背景色
    $(":animated").css("background","#bbffaa");

    动画效果如下:

    image-20211216094031802
    image-20211216094104872

    2.内容过滤选择器

    内容过滤选择器的过滤规则主要体现在它所包含的子元素或文本内容上。内容过滤选择器的介绍说明如表2-10所示。

    表2-10 内容过滤选择器
    选择器 描述 返回 示例
    :contains(text) 选取含有文本内容为“text”的元素 集合元素 $("div:contains('我')")选取含有文本“我”的<div>
    :empty 选取不包含子元素或者文本的空元素 集合元素 $("div:empty")选取不包含子元素(包括文本元素)的<div>空元素
    :has(selector) 选取含有选择器所匹配的元素的元素 集合元素 $("div:has(p)")选取含有<p>元素的<div>元素
    :parent 选取含有子元素或者文本的元素 集合元素 $("div:parent")选取拥有子元素(包括文本元素)的<div>元素

    接下来使用内容过滤选择器来操作页面中的元素,示例如表2-11所示。

    表2-11 内容过滤选择器示例
    功能 代码 执行后
    改变含有文本”di”的<div>元素的背景色 $("div:contains(di)").css("background","#bbffaa"); image-20211216150423081
    改变不包含子元素(包括文本元素)的<div>空元素的背景色 $("div:empty").css("background","#bbffaa"); image-20211216150530814
    改变含有class为mini元素的<div>元素的背景色 $("div:has('.mini')").css("background","#bbffaa"); image-20211216150716592
    改变含有子元素(包括文本元素)的<div>元素的背景色 $("div:parent").css("background","#bbffaa"); image-20211216150900129

    3.可见性过滤选择器

    可见性过滤选择器是根据元素的可见和不可见状态来选择相应的元素。可见性过滤选择器的介绍说明如表2-12所示。

    表2-12 可见性过滤选择器
    选择器 描述 返回 示例
    :hidden 选取所有不可见的元素 集合元素 $(":hidden")选取所有不可见的元素。包括<inputtype="hidden"/><divstyle="display:none;"><divstyle="visibility:hidden;"/>等元素。如果只想选取<input>元素,可以使用$("input:hiddren")
    :visible 选取所有可见的元素 集合元素 $("div:visible")选取所有可见的<div>元素

    在例子中使用这些选择器来操作DOM元素,示例如表2-13所示。

    表2-13 可见性过滤选择器示例
    功能 代码 执行后
    改变所有可见的<div>元素的背景色 $("div:visible").css("background","#FF6500"); image-20211216152217712
    显示隐藏的<div>元素 $("div:hidden").show(3000)
    $(":animated").css("background","#bbffaa");
    image-20211216152555314

    在可见性选择器中,需要注意选择器:hidden,它不仅包括样式属性display为“none”的元素,也包括文本隐藏域(<input type="hidden"/>)和visibility:hidden之类的元素。

    注意:show()是jQuery的方法,它的功能是显示元素,3000是时间,单位是毫秒。

    4.属性过滤选择器

    属性过滤选择器的过滤规则是通过元素的属性来获取相应的元素。属性过滤选择器的介绍说明如表2-14所示。

    表2-14 属性过滤选择器
    选择器 描述 返回 示例
    [atrribute] 选取拥有此属性的元素 集合元素 $("div[id]")选取用拥有属性id的元素
    [attribute=value] 选取属性的值为value的元素 集合元素 $("div[title=test]")选取属性title为“test”的<div>元素
    [attribute!=value] 选取属性的值不等于value的元素 集合元素 $("div[title!=test]")选取属性title不等于“test”的<div>元素(注意:没有title属性的<div>元素也会被选取)
    [attribute^=value] 选取属性的值以value开头的元素 集合元素 $("div[title^test]")选取属性title以“test”开头的<div>元素
    [attribute$=value] 选取属性的值以value结尾的元素 集合元素 $("div[title$=test]")选取属性title以“test”结尾的<div>元素
    [attribute*=value] 选取属性的值含有value的元素 集合元素 $("div[title*=test]")选取属性title含有“test”的<div>元素
    `[attitude =value]` 选取属性值等于给定字符串或者以该字符串为前缀(该字符串后跟着一个连字符“-”)的元素 集合元素
    [attibute~=value] 选取属性用空格分隔的值中包含一个给定值的元素 集合元素 $("div[title~='uk']")选取属性title中空格分隔的值中包含字符uk的元素。
    [attribute1][attribute2]...[attributeN] 用属性选择器合成一个复合属性选择器,满足多个条件。每选择一次,缩小一次范围 集合元素 $("div[id][title$='test']")选取拥有属性id,并且属性title以“test”结束的<div>元素。

    接下来使用属性过滤选择器来对<div><span>等元素进行操作,示例如表2-15所示。

    表2-15 属性过滤选择器示例
    功能 代码 执行后
    改变含有属性title的<div>元素的背景色 $("div[title]").css("background","#bbffaa"); image-20211216194623728
    改变属性title值等于test的<div>元素的背景色 $("div[title=test]").css("background","#bbffaa"); image-20211216194819301
    改变属性title值不等于“test”的<div>元素的背景色 $("div[title!=test]").css("background","#bbffaa"); image-20211216194947309
    改变属性title值以“te”开始的<div>元素的背景色 $("div[title^=te]").css("background","#bbffaa"); image-20211216195100035
    改变属性title值以“est”结束的<div>元素的背景色 $("div[title$=est]").css("background","#bbffaa"); image-20211216195203888
    改变属性title值含有”es”的<div>元素的背景色 $("div[title*=es]").css("background","#bbffaa"); image-20211216195318051
    改变含有有属性id,并且属性title值含有“es”的<div>元素的背景色 $("div[id][title*=es]").css("background","#bbffaa"); image-20211216195417858

    jQuery属性选择器的过滤规则比较多,特别容易混淆。为此,我把几个容易混淆的单独做了一个例子,以加强印象。HTML代码如下:

    1
    2
    3
    4
    5
    <div title="en">title为en的div元素</div>
    <div title="en-UK">title为en-UK的div元素</div>
    <div title="english">title为english的div元素</div>
    <div title="en uk">title为en uk的div元素</div>
    <div title="uken">title为uken的div元素</div>

    生成的效果图如图2-3所示。

    image-20211216200328043

    图2-3 初始状态现在用jQuery的表单过滤选择器来操作它们,示例如表2-16所示。
    表2-16 属性过滤选择器示例
    功能 代码 执行后
    改变属性title值以“en”开始的<div>元素的背景色 $("div[title^='en']").css("background","#bbffaa"); image-20211216201336681
    改变属性title值含有“en”的<div>元素的背景色 $("div[title*='en']").css("background","#bbffaa"); image-20211216201501273
    改变属性title等于“en”或以en为前缀(以该字符串后给有一个连字符’=’) `$(“div[title =’en’]”).css(“background”,”#bbffaa”);`
    改变属性title用空格分隔的值中包含字符uk的元素的背景色 $("div[title~='uk']").css("background","#bbffaa"); image-20211216201708505

    5.子元素过滤选择器

    子元素过滤选择器的过滤规则相对于其它的选择器稍微有些复杂,不过没关系,只要将元素的父元素和子元素区分清楚,那么使用起来也非常简单。另外还要注意它与普通的过滤选择器的区别。

    子元素过滤选择器的介绍说明如表2-17所示。

    表2-17 子元素过滤选择器
    选择器 描述 返回 示例
    :nth-child(index/even/odd/equation) 选取每个父元素下的第index个子元素或者奇偶元素。(index从1算起) 集合元素 :eq(index)只匹配一个元素,而:nth-child将为每一个父元素匹配子元素,并且:nth-child(index)的index是从1开始的,而:eq(index)是从0算起的
    :first-child 选取每个父元素的第1个子元素 集合元素 :first只返回单个元素,而:first-child选择符将为每个父元素匹配第1个子元素。
    例如$("ul li:first-child");选取每个<ul>中第1个<li>元素
    :last-child 选取每个父元素的最后一个子元素 集合元素 同样,:last只返回单个元素,而:last-child选择符将为每个父元素匹配最后一个子元素。
    例如$("ul li:last-child");选择每个<ul>中最后一个<li>元素
    :only-child 如果某个元素是它父元素惟一的子元素,那么将会被匹配。如果父元素中含有其他元素,则不会被匹配 集合元素 $("ul li:only-child")<ul>中选取是惟一子元素的<li>元素

    :nth-child()选择器是很常用的子元素过滤选择器,详细功能如下。

    (1):nth-child(even)能选取每个父元素下的索引值是偶数的元素。
    (2):nth-child(odd)能选取每个父元素下的索引值是奇数的元素。
    (3):nth-child(2)能选取每个父元素下的索引值等于2的元素。
    (4):nth-child(3n)能选取每个父元素下的索引值是3的倍数的元素,(n从1开始)。
    (5):nth-child(3n+1)能选取每个父元素下的索引值是(3n+1)的元素。(n从1开始)

    接下来利用刚才所讲的选择器来改变<div>元素的背景色,示例如表2-18所示。

    表2-18 子元素过滤选择器示例
    功能 代码 执行后
    改变每个class为one的<div>父元素下的第2个子元素的背景色 $("div.one :nth-child(2)").css("background","#bbffaa"); image-20211217111518207
    改变每个class为one的<div>父元素下的第1个元素的背景色 $("div.one :first-child").css("background","#bbffaa"); image-20211217111639646
    改变每个class为one的<div>父元素下的最后一个子元素的背景色 $("div.one :last-child").css("background","#bbffaa"); image-20211217111746411
    如果class为one的div父元素下只有一个子元素,那么则改变这个子元素的背景色 $("div.one :only-child").css("background","#bbffaa"); image-20211217111909275
    注意:eq(index)只匹配一个元素,而:nth-child 将为每一个符合条件的父元素匹配子元素。同时应该注意到 nth-child(index)的index是从 1 开始的,而:eq(index)是从 0 开始的。同理:first和:first-child,:last和:last-child也类似。

    6.表单对象属性过滤选择器

    此选择器主要是对所选择的表单元素进行过滤,例如选择被选中的下拉框,多选框等元素。表单对象属性过滤选择器的介绍说明如表2-19所示。

    表2-19 表单对象属性过滤选择器
    选择器 描述 返回 示例
    :enabled 选取所有可用元素 集合元素 $("form1:enabled");选取id为“form1”的表单内的所有可用元素
    :disabled 选取所有不可用元素 集合元素 $("form2:disabled");选取id为“form2”的表单内的所有不可用元素
    :checked 选取所有被选中的元素(单选框,复选框) 集合元素 $("input:checked");选取所有被选中的<input>元素
    :selected 选取所有被选中的选项元素(下拉列表) 集合元素 $("selectoption:selected");选取所有被选中的选项元素

    为了演示这些选择器,需要制作一个包含表单的网页,里面要包含文本框、多选框和下拉列表,HTML代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <form id="form1" action="#">
    可用元素:<input name="add" value="可用文本框" /> <br />
    不可用元素:<input name="email" disabled="disabled" value="不可用文本框" /><br />
    可用元素: <input name="che" value="可用文本框" /><br />
    不可用元素:<input name="name" disabled="disabled" value="不可用文本框" /><br />
    <br />
    多选框:<br />
    <input type="checkbox" name="newsletter" checked="checked" value="test1" />test1
    <input type="checkbox" name="newsletter" value="test2" />test2
    <input type="checkbox" name="newsletter" value="test3" />test3
    <input type="checkbox" name="newsletter" checked="checked" value="test4" />test4
    <input type="checkbox" name="newsletter" value="test5" />test5
    <div></div>
    <br /><br />
    下拉列表1:<br />
    <select name="test" multiple="multiple" style="height:100px">
    <option>浙江</option>
    <option selected="selected">湖南</option>
    <option>北京</option>
    <option selected="selected">天津</option>
    <option>广州</option>
    <option>湖北</option>
    </select>
    <br /><br />
    下拉列表2:<br />
    <select name="test2">
    <option>浙江</option>
    <option>湖南</option>
    <option selected="selected">北京</option>
    <option>天津</option>
    <option>广州</option>
    <option>湖北</option>
    </select>
    <div></div>
    </form>

    生成的效果图如图2-4所示。

    image-20211217113205473

    图2-4 初始状态

    现在用jQuery的表单过滤选择器来操作它们,示例如表2-20所示。

    表2-20 表单对象属性过滤示例
    作用 代码 执行后
    改变表单内可用<input>元素的值 $("#form1 input:enabled").val("这里变化了!"); image-20211217132330216
    改变表单内不可用<input>元素的值 $("#form1 input:disabled").val("这里变化了!"); image-20211217132504426
    获取多选框中的个数 $("input:checked").length; image-20211217145226475
    获取下拉框选中的内容 $("select:selected").text(); image-20211217153852108

    上表中的后两项测试代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <form id="form1" action="#">
    可用元素:<input name="add" value="可用文本框" /> <br />
    不可用元素:<input name="email" disabled="disabled" value="不可用文本框" /><br />
    可用元素: <input name="che" value="可用文本框" /><br />
    不可用元素:<input name="name" disabled="disabled" value="不可用文本框" /><br />
    <br />
    多选框:<br />
    <input type="checkbox" name="newsletter" checked="checked" value="test1" />test1
    <input type="checkbox" name="newsletter" value="test2" />test2
    <input type="checkbox" name="newsletter" value="test3" />test3
    <input type="checkbox" name="newsletter" checked="checked" value="test4" />test4
    <input type="checkbox" name="newsletter" value="test5" />test5
    <div id="checkbox_div"></div>
    <br /><br />
    下拉列表1:<br />
    <select name="test" multiple="multiple" style="height:100px">
    <option>浙江</option>
    <option selected="selected">湖南</option>
    <option>北京</option>
    <option selected="selected">天津</option>
    <option>广州</option>
    <option>湖北</option>
    </select>
    <br /><br />
    下拉列表2:<br />
    <select name="test2">
    <option>浙江</option>
    <option>湖南</option>
    <option selected="selected">北京</option>
    <option>天津</option>
    <option>广州</option>
    <option>湖北</option>
    </select>
    <div id="select_div"></div>
    </form>

    js代码:

    1
    2
    3
    4
    5
    6
    7
    8
    // 获取多选框中的个数
    $('input[name=newsletter]').change(function() {
    $("#checkbox_div").html("<strong>有" + $("input:checked").length + "个被选中!</strong>");
    });
    // 获取下拉框选中的内容
    $("select").change(function () {
    $("#select_div").html("<strong>你选中的是,"+$("select :selected").text()+"</strong>")
    })

    2.3.4 表单选择器

    为了使用户能够更加灵活地操作表单,jQuery中专门加入了表单选择器。利用这个选择器,能极其方便地获取到表单的某个或某类型的元素。

    表单选择器的介绍说明如表2-21所示。

    表2-21 表单对象属性过滤示例
    选择器 描述 返回 示例
    :input 选取所有的<input><textarea>,<select><button>元素 集合元素 $(":input")选取所有<input><textarea><button>元素
    :text 选取所有的单行文本框 集合元素 $(":text")选取所有的单行文本框
    :password 选取所有的密码框 集合元素 $(":password")选取所有的密码框
    :radio 选取所有的单选框 集合元素 $(":radio")选取所有的单选框
    :checkbox 选取所有的多选框 集合元素 $(":checkbox")选取所有的复选框
    :submit 选取所有的提交按钮 集合元素 $(":submit")选取所有的提交按钮
    :image 选取所有的图像按钮 集合元素 $("image")选取所有的图像按钮
    :reset 选取所有的重置按钮 集合元素 $(":reset")选取所有的重置按钮
    :button 选取所有的按钮 集合元素 $(":button")选取所有的按钮
    :file 选取所有的上传域 集合元素 $(":file")选取所有的上传域
    :hidden 选取所有的不可见元素 集合元素 $(":hidden")选取所有不可见元素(已经在不可见性过滤选择器中讲解过)

    下面把这些表单选择器运用到下面的表单中,对表单进行操作。

    表单HTML代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <form id="form1" action="#">
    <input type="button" value="Button" /><br />
    <input type="checkbox" name="c" />1
    <input type="checkbox" name="c" />2
    <input type="checkbox" name="c" />3<br />
    <input type="file" /><br />
    <input type="hidden" />
    <div style="display:none">test</div><br />
    <input type="image" /><br />
    <input type="password" /><br />
    <input type="radio" name="a" />1<input type="radio" name="a" />2<br />
    <input type="reset" /><br />
    <input type="submit" value="提交" /><br />
    <input type="text" /><br />
    <select>
    <option>Option</option>
    </select><br />
    <textarea></textarea><br />
    <button>Button</button><br />
    </form>
    <div id="show"></div>

    根据以上HTML代码,可以生成图2-5所示的页面效果。

    image-20211217170509168

    图2-5 初始状态

    如果想得到表单内表单元素的个数,代码如下:

    1
    $("#form1 :input").length;

    如果想得到表单内单行文本框的个数,代码如下:

    1
    $("#form1 :text").length;

    如果想得到表单内密码框的个数,代码如下:

    1
    $("#form1 :password").length;

    同理,其他表单选择器的操作与此类似。

    测试代码:

    1
    2
    3
    4
    var text = "&lt;input&gt;元素的个数:" + $("#form1 :input").length + "<br>";
    text += "&lt;input type='text'&gt;元素的个数:" + $("#form1 :text").length + "<br>";
    text += "&lt;input type='password'&gt;元素的个数:" + $("#form1 :password").length + "<br>";
    $("#show").html(text);

    运行效果:
    image-20211217170701172

    2.2 jQuery选择器的优势

    1.简洁的写法

    $()函数在很多 JavaScript 类库中都被作为一个选择器函数来使用,在 jQuery 中也不例外。其中,$("#ID")用来代替document.getElementById()函数,即通过ID获取元素;$("tagName")用来代替document.getElementsByTagName()函数,即通过标签名获取HTML元素;其他选择器的写法可以参见第2.3节。

    2.支持CSS 1到CSS 3选择器

    jQuery选择器支持CSS 1、CSS 2的全部和CSS 3的部分选择器,同时它也有少量独有的选择器,因此对拥有一定CSS基础的开发人员来说,学习jQuery选择器是件非常容易的事,而对于没有接触过CSS技术的开发人员来说,在学习jQuery选择器的同时也可以掌握CSS选择器的基本规则。

    使用CSS选择器时,开发人员需要考虑主流浏览器是否支持某些选择器。而在jQuery中, 开发人员则可以放心地使用jQuery选择器而无需考虑浏览器是否支持这些选择器。

    注意:为了能有更快的选择器解析速度,从1.1.3.1版以后,jQuery废弃了不常使用的XPath选择器,但在引用相关插件后,依然可以支持XPath选择器(详见第2.7.1小节)。

    3.完善的处理机制

    使用jQuery选择器不仅比使用传统的getElementById()和getElementsByTagName()函数简洁得多,而且还能避免某些错误。看下面这个例子,代码如下:

    1
    2
    3
    4
    <div>test</div>
    <script type="text/javascript">
    document.getElementById("tt").style.color="red";
    </script>

    运行上面的代码,浏览器就会报错,原因是网页中没有id为“tt”的元素。

    改进后的代码如下:

    1
    2
    3
    4
    5
    6
    <div>test</div>
    <script type="text/javascript">
    if(document.getElementById("tt")){
    document.getElementById("tt").style.color="red";
    }
    </script>

    这样就可以避免浏览器报错,但如果要操作的元素很多,可能对每个元素都要进行一次判断,大量重复的工作会使开发人员感到厌倦,而 jQuery 在这方面问题上的处理是非常不错的,即使用jQuery获取网页中不存在的元素也不会报错,看下面的例子,代码如下:

    1
    2
    3
    4
    5
    <div>test</div>
    <script type="text/javascript">
    //这里无需判断$('#tt')是否存在
    $('#tt').css("color", "red");
    </script>

    有了这个预防措施,即使以后因为某种原因删除网页上某个以前使用过的元素,也不用担心这个网页的JavaScript代码会报错。

    需要注意的是,$('#tt')获取的永远是对象,即使网页上没有此元素。因此当要用jQuery检查某个元素在网页上是否存在时,不能使用以下代码:

    1
    2
    3
    if ( $("#tt") ) {
    //do something
    }

    而应该根据获取到元素的长度来判断,代码如下:

    1
    2
    3
    if ( $("#tt").length > 0 ) {
    //do something
    }

    或者转化成DOM对象来判断,代码如下:

    1
    2
    3
    if ( $("#tt")[0]  ) {
    //do something
    }

    第2章 jQuery选择器

    选择器是jQuery的根基,在jQuery中,对事件处理、遍历DOM和Ajax操作都依赖于选择器。如果能熟练地使用选择器,不仅能简化代码,而且可以达到事半功倍的效果。

    2.1 jQuery选择器是什么

    1.CSS选择器

    在开始学习 jQuery 选择器之前,有必要简单了解前几年流行起来的CSS(Cascading Style Sheets,层叠样式表)技术。CSS是一项出色的技术,它使得网页的结构和表现样式完全分离。利用CSS选择器能轻松地对某个元素添加样式而不改动HTML结构,只需通过添加不同的CSS规则,就可以得到各种不同样式的网页。

    要使某个样式应用于特定的HTML元素,首先需要找到该元素。在CSS中,执行这一任务的表现规则称为CSS选择器。学会使用CSS选择器是学习CSS的基础,它为在获取目标元素之后施加样式提供了极大的灵活性。常用的CSS选择器分类如表2-1所示。

    表2-1 常用的CSS选择器

    epub_731606_43

    几乎所有主流浏览器都支持上面这些常用的选择器。此外CSS中还有伪类选择器(E:Pseudo-Elements{ CssRules })、子选择器(E > F{ CssRules })、临近选择器(E + F { CssRules })和属性选择器(E [ attr ] { CssRules })等。但遗憾的是,主流浏览器并非完全支持所有的CSS选择器。

    更加详细的介绍可以参考http://www.w3.org/TR/CSS2/selector.html 网址。

    了解这些相关知识后,来看一个有关CSS类选择器的简单例子,代码如下:

    1
    <p style="color:red;font-size:30px;">CSS Demo</p>

    上面代码的意思是将<p>元素里的文本颜色设置为红色,字体大小设置为30px。

    像上面这样把CSS代码和HTML代码混杂在一起的做法是非常不妥的,它并不符合表现和内容相分离的设计原则,因此建议使用下面的方法,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <style>
    /*给class为demo的元素添加样式*/
    .demo {
    color: red;
    font-size: 30px;
    }
    </style>
    <p class="demo">CSS Demo.</p>

    先把样式写在<style>标签里,然后用class属性将元素和样式联系起来,class作为连接样式和网页结构的纽带。这样的写法不仅容易理解和阅读,而且当需要改变一些样式的时候,只要在<style>标签里改变相关的样式即可。

    例如要使所有class为demo的<p>元素里的字体加粗,可以直接在<style>里编写,而不需要去网页里寻找所有class为demo的<p>元素再逐个添加样式,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <style>
    /*给class为demo的元素添加样式*/
    .demo {
    color: red;
    font-size: 30px;
    /*字体加粗*/
    font-weight: bold;
    }
    </style>
    <p class="demo">CSS Demo.</p>
    :把CSS应用到网页中有3种方式,即行间样式表、内部样式表和外部样式表。上例中使用的是内部样式表,内部样式表的缺点是不能被多个页面重复使用。

    2.jQuery选择器

    jQuery中的选择器完全继承了CSS的风格。利用jQuery选择器,可以非常便捷和快速地找出特定的DOM元素,然后为它们添加相应的行为,而无需担心浏览器是否支持这一选择器。学会使用选择器是学习jQuery的基础,jQuery的行为规则都必须在获取到元素后才能生效。

    下面来看一个简单的例子,代码如下:

    1
    2
    3
    4
    5
    6
    <script type="text/javascript">
    function demo() {
    alert('JavaScript demo.');
    }
    </script>
    <p onclick="demo();">点击我.</p>

    本段代码的作用是为<p>元素设置一个onclick事件,当单击此元素时,会弹出一个对话框,显示效果如图2-1所示。

    image-20211214210228808

    图2-1 弹出警告框

    像上面这样把JavaScript代码和HTML代码混杂在一起的做法同样也非常不妥,因为它并没有将网页内容和行为分离,所以建议使用下面的方法,代码如下:

    1
    2
    3
    4
    5
    6
    7
    <p class="demo">jQuery Demo</p>
    <script type="text/javascript">
    //给class为demo的元素添加行为
    $(".demo").click(function () {
    alert("jQuery demo!");
    })
    </script>

    此时,可以对CSS的写法和jQuery的写法进行比较。

    CSS获取到元素的代码如下:

    1
    2
    3
    4
    /*给class为demo的元素添加样式*/
    .demo {
    ...
    }

    jQuery获取到元素的代码如下:

    1
    2
    3
    4
    //给class为demo的元素添加行为
    $(".demo").click(function(){
    ...
    }

    jQuery选择器的写法与CSS选择器的写法十分相似,只不过两者的作用效果不同,CSS选择器找到元素后是添加样式,而 jQuery 选择器找到元素后是添加行为。需要特别说明的是,jQuery中涉及操作CSS样式的部分比单纯的CSS功能更为强大,并且拥有跨浏览器的兼容性。