3.2 jQuery中的DOM操作
3.2 jQuery中的DOM操作
为了能全面地讲解DOM操作,首先需要构建一个网页。因为每一张网页都能用DOM表示出来,而每一份DOM都可以看作一棵DOM树。构建的网页效果如图3-1所示。
[插图]
HTML代码如下:
[插图]
根据上面的网页结构构建出一棵DOM树,如图3-2所示。
[插图]
接下来,对DOM的各种操作都将围绕这棵DOM树而展开。
3.2.1 查找节点
使用jQuery在文档树上查找节点非常容易,可以通过在第2章介绍的jQuery选择器来完成。
1.查找元素节点
获取元素节点并打印出它的文本内容,jQuery代码如下:
[插图]
以上代码获取了<ul>
元素里第2个<li>
节点,并将它的文本内容“橘子”打印出来,效果如图3-3所示。
[插图]
2.查找属性节点
利用 jQuery 选择器查找到需要的元素之后,就可以使用 attr()方法来获取它的各种属性的值。attr()方法的参数可以是一个,也可以是两个。当参数是一个时,则是要查询的属性的名字,例如:
获取属性节点并打印出它的文本内容,jQuery代码如下:
[插图]
以上代码获取了<p>
节点,并将它的title属性的值打印出来,效果如图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代码如下:
[插图]
`元素,可以用$("<p/>")
或者$("<p></p>")
,但不要使用$("<p>")
或者大写的$("<P/>")
。
运行代码后,新创建的<li>
元素将被添加到网页中,因为暂时没有在它们内部添加任何文本,所以只能看到<li>
元素默认的“· ”,如图3-5所示。
[插图]
2.创建文本节点
已经创建了两个<li>
元素节点并把它们插入文档中了。此时需要为创建的元素节点添加文本内容。
jQuery代码如下:
[插图]
如以上代码所示,创建文本节点就是在创建元素节点时直接把文本内容写出来,然后使用append()等方法将它们添加到文档中就可以了。
创建的<li>
节点显示到网页中的效果如图3-6所示。
[插图]
$(html)
中的HTML代码多么复杂,都可以使用相同的方式来创建。例如$("这是一个复杂的组合 ")
;3.创建属性节点
创建属性节点与创建文本节点类似,也是直接在创建元素节点时一起创建。jQuery代码如下:
[插图]
运行代码后,效果如图3-7所示。
[插图]
读者也许会发现图3-7与图3-6显示的效果没有什么区别,但事实上两者还是有差别的,可以通过Firebug工具来查看比较。
图3-6的网页内容在Firebug工具下显示的效果如图3-8所示。
[插图]
图3-7的网页内容在Firebug工具下显示的效果如图3-9所示。
[插图]
通过比较图3-8和图3-9对应的代码,发现图3-9的代码中最后两个<li>
元素多了名为“title”的属性节点。由此可以判断,创建的元素的文本节点和属性节点都已经添加到网页中了。
由此可见用jQuery来动态创建HTML元素是非常简单、方便和灵活的。
3.2.3 插入节点
动态创建 HTML 元素并没有实际用处,还需要将新创建的元素插入文档中。将新创建的节点插入文档最简单的办法是,让它成为这个文档的某个节点的子节点。前面使用了一个插入节点的方
法append(),它会在元素内部追加新创建的内容。
将新创建的节点插入某个文档的方法并非只有一种,在 jQuery 中还提供了其他几种插入节点的方法,如表3-1所示。读者可以根据实际需求灵活地做出多种选择。
[插图]
这些插入节点的方法不仅能将新创建的DOM元素插入到文档中,也能对原有的DOM元素进行移动。
例如利用它们创建新元素并对其进行插入操作。
jQuery代码如下:
[插图]
运行代码后,网页呈现效果如图3-10所示。
[插图]
例如利用它们对原有的DOM元素进行移动。
jQuery代码如下:
[插图]
运行代码后,网页呈现效果如图3-12所示。
[插图]
3.2.4 删除节点
如果文档中某一个元素多余,那么应将其删除。jQuery 提供了三种删除节点的方法,即remove(),detach()和empty()。
1.remove()方法
作用是从DOM中删除所有匹配的元素,传入的参数用于根据jQuery表达式来筛选元素。例如删除图3-11中<ul>
节点中的第2个<li>
元素节点,jQuery代码如下:
[插图]
[插图]
运行代码后效果如图3-13所示。
[插图]
当某个节点用remove()方法删除后,该节点所包含的所有后代节点将同时被删除。这个方法的返回值是一个指向已被删除的节点的引用,因此可以在以后再使用这些元素。下面的jQuery 代码说明元素用remove()方法删除后,还是可以继续使用的。
[插图]
可以直接使用appendTo()方法的特性来简化以上代码,jQuery代码如下:
[插图]
[插图]
另外remove()方法也可以通过传递参数来选择性地删除元素,jQuery代码如下:
[插图]
运行代码后,效果如图3-15所示。
[插图]
在Firebug工具中查看源代码,如图3-16所示。
[插图]
2.detach()方法
detach()和remove()一样,也是从DOM中去掉所有匹配的元素。但需要注意的是,这个方法不会把匹配的元素从 jQuery 对象中删除,因而可以在将来再使用这些匹配的元素。与 remove()不同的是,所有绑定的事件、附加的数据等都会保留下来。
通过下面的例子,可以知道它与remove()方法的区别,jQuery代码如下:
[插图]
3.empty()方法
严格来讲,empty()方法并不是删除节点,而是清空节点,它能清空元素中的所有后代节点。jQuery代码如下:
[插图]
当运行代码后,第2个<li>
元素的内容被清空了,只剩下<li>
标签默认的符号“·”,效果如图3-17所示。
[插图]
在Firebug工具中查看源代码,如图3-18所示。
[插图]
3.2.5 复制节点
复制节点也是常用的DOM操作之一,例如图3-19所示的某个购物网站的效果,用户不仅可以通过单击商品下方的“选择”按钮购买相应的产品,也可以通过鼠标拖动商品并将其放到购物车中。这个商品拖动功能就是用的复制节点,将用户选择的商品所处的节点元素复制一次,并将其跟随鼠标移动,从而达到以下购物效果。
[插图]
继续沿用之前的例子,如果单击<li>
元素后需要再复制一个<li>
元素,可以使用clone()方法来完成,jQuery代码如下:
[插图]
在页面中单击“菠萝”后,列表最下方出现新节点“菠萝”,效果如图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.2.7 包裹节点
如果要将某个节点用其他标记包裹起来,jQuery提供了相应的方法,即wrap()。该方法对于需要在文档中插入额外的结构化标记非常有用,而且它不会破坏原始文档的语义。
jQuery代码如下:
[插图]
得到的结果如下:
[插图]
在Firebug工具中查看源文件,效果如图3-22所示。
[插图]
包裹节点操作还有其他两个方法,即wrapAll()和wrapInner()。
1.wrapAll()方法
该方法会将所有匹配的元素用一个元素来包裹。它不同于wrap()方法,wrap()方法是将所有的元素进行单独的包裹。
为了使效果更突出,在网页中再加入一个<strong>
元素。
HTML代码如下:
[插图]
如果使用wrap()方法包裹<strong>
元素,jQuery代码如下:
[插图]
将会得到如下结果:
[插图]
用Firebug工具查看源文件的效果如图3-23所示。
[插图]
使用wrapAll()方法包裹<strong>
元素,jQuery代码如下:
[插图]
则会得到如下结果:
[插图]
[插图]
用Firebug工具查看源文件的效果如图3-24所示。
[插图]
2.wrapInner()方法
该方法将每一个匹配的元素的子内容(包括文本节点)用其他结构化的标记包裹起来。例如可以使用它来包裹<strong>
标签的子内容,jQuery代码如下:
[插图]
运行代码后,发现<strong>
标签内的内容被一对<b>
标签包裹了,结果如下:
[插图]
使用Firebug工具查看网页结构,显示效果如图3-25所示。
[插图]
3.2.8 属性操作
在jQuery中,用attr()方法来获取和设置元素属性,removeAttr()方法来删除元素属性。
1.获取属性和设置属性
如果要获取<p>
元素的属性title,那么只需要给attr()方法传递一个参数,即属性名称。
jQuery代码如下:
[插图]
如果要设置<p>
元素的属性title的值,也可以使用同一个方法,不同的是,需要传递两个参数即属性名称和对应的值。
jQuery代码如下:
[插图]
如果需要一次性为同一个元素设置多个属性,可以使用下面的代码来实现:
[插图]
2.删除属性
在某些情况下,需要删除文档中某个元素的特定属性,可以使用 removeAttr()方法来完成该任务。
如果需要删除<p>
元素的title属性,可以使用下面的代码实现:
[插图]
运行代码后,<p>
元素的title属性将被删除。此时<p>
元素的HTML结构由
[插图]
变为
[插图]
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所示。
[插图]
在Firebug工具中查看class代码如图3-27所示。
[插图]
此时<p>
元素同时拥有两个class值,即“high”和“another”。在CSS中有以下两条规定。
(1)如果给一个元素添加了多个class值,那么就相当于合并了它们的样式。
(2)如果有不同的class设定了同一样式属性,则后者覆盖前者。
在上例中,相当于给<p>
元素添加了如下样式:
[插图]
在以上的样式中,存在两个“color”属性,而后面的“color”属性会覆盖前面的“color”属性,因此最终的“color”属性的值为“blue”,而不是“red”。
样式最终呈现为:
[插图]
追加样式和设置样式的区别如表3-2所示。
[插图]
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:
[插图]
3.2.10 设置和获取HTML、文本和值
1.html()方法
此方法类似于JavaScript中的innerHTML属性,可以用来读取或者设置某个元素中的HTML内容。
为了更清楚地展示效果,将<p>
元素的HTML代码改成:
[插图]
然后用html()方法对<p>
元素进行操作:
[插图]
运行代码后,效果如图3-28所示。
[插图]
`元素的HTML代码
如果需要设置某元素的HTML 代码,那么也可以使用该方法,不过需要为它传递一个参数。例如要设置<p>
元素的HTML代码,可以使用如下代码:
[插图]
2.text()方法
此方法类似于JavaScript中的innerText属性,可以用来读取或者设置某个元素中的文本内容。继续使用以上的HTML代码:
[插图]
用text()方法对<p>
元素进行操作:
[插图]
运行代码后,效果如图3-29所示:
[插图]
`元素的文本内容
与 html()方法一样,如果需要为某元素设置文本内容,那么也需要传递一个参数。例如对<p>
元素设置文本内容,代码如下:
[插图]
3.val()方法
此方法类似于 JavaScript 中的value 属性,可以用来设置和获取元素的值。无论元素是文本框,下拉列表还是单选框,它都可以返回元素的值。如果元素为多选,则返回一个包含所有选择的值的数组。
如图3-30所示,这是某网站的邮箱登录界面,默认状态下,邮箱地址文本框和邮箱密码框内分别有“请输入邮箱地址”和“请输入邮箱密码”的提示。
[插图]
当将鼠标聚焦到邮箱地址文本框时,文本框内的“请输入邮箱地址”文字将被清空,效果如图3-31所示。
[插图]
如果此时未在邮箱地址框中输入任何内容,而将鼠标焦点直接聚焦到密码输入框,则会发现密码框内的提示文字被清空了,同时邮箱地址输入框的提示也被还原了,效果如图3-32所示。
[插图]
要实现以上例子展示的功能,可以使用val()方法。实现步骤如下。
第1步:设计网页的基本结构。在页面中添加两个文本框,分别对两个文本框设置id,同时设置它们的默认值为“请输入邮箱地址”和“请输入邮箱密码”。
HTML代码如下:
[插图]
呈现的网页效果如图3-33所示。
[插图]
第2步:对“地址框”进行操作。
当地址框获取鼠标焦点时,如果地址框的值为“请输入邮箱地址”,则将地址框中的值清空。可以使用如下的jQuery代码:
[插图]
当地址框失去鼠标焦点时,如果地址框的值为空,则将地址框的值设置为“请输入邮箱地址”。可以使用如下的jQuery代码:
[插图]
第3步:对“密码框”进行操作,实现过程与“地址框”相同。
此时,类似于YAHOO邮箱登录框的提示效果就完成了。完整代码如下:
[插图]
在该例子中,也可以使用表单元素的defaultValue属性来实现同样的功能,defaultValue属性包含该表单元素的初始值。代码如下:
[插图]
通过上面的例子可以发现val()方法不仅能设置元素的值,同时也能获取元素的值。另外,val()方法还有另外一个用处,就是它能使select(下拉列表框)、checkbox(多选框)和radio(单选框)相应的选项被选中,在表单操作中会经常用到。
下面构建一个网页来演示val()方法的选中功能。
HTML代码如下:
[插图]
运行代码后,显示效果如图3-34所示。
[插图]
该网页中一些元素是默认选中的,可以通过 val()方法来改变它们的选中项。如果要使第1个下拉框的第2项被选中,可以用以下jQuery代码实现:
[插图]
如果要使下拉列表的第2项和第3项被选中,可以用以下jQuery代码实现:
[插图]
依照上面类似的写法,下面的代码可以使多选框和单选框被选中,jQuery代码如下:
[插图]
运行代码后,显示效果如图3-35所示。
[插图]
[插图]
3.2.11 遍历节点
1.children()方法
该方法用于取得匹配元素的子元素集合。
此处使用本章开头所画的那颗DOM树的结构,如图3-36所示。
[插图]
根据DOM树的结构,可以知道各个元素之间的关系以及它们子节点的个数。<body>
元素下有<p>
和<ul>
两个子元素,<p>
元素没有子元素,<ul>
元素有3个<li>
子元素。
下面使用children()方法来获取匹配元素的所有子元素的个数。
jQuery代码如下:
[插图]
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所示。读者可以根据实际需求灵活地选择使用哪个方法。
[插图]
除此之外,在 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()方法也可以同时设置多个样式属性,代码如下:
[插图]
对透明度的设置,可以直接使用opacity属性,jQuery已经处理好了兼容性的问题,如下代码所示,将<p>
元素的透明度设置为半透明:
[插图]
如果需要获取某个元素的height属性,则可以通过如下jQuery代码实现:
[插图]
在jQuery中还有另外一种方法也可以获取元素的高度,即height()。它的作用是取得匹配元素当前计算的高度值(px)。jQuery代码如下:
[插图]
height()方法也能用来设置元素的高度,如果传递的值是一个数字,则默认单位为px。如果要用其他单位(例如em),则必须传递一个字符串。jQuery代码如下:
[插图]
与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操作的实例。