在很多时候,需要通过JavaScript动态的在网页中添加或删除HTML元素,尤其在使用AJAX技术时!如果选择JQuery框架只是为了搜索页面元素,然后设置样式或属性,那未免有点舍大而去小。我认为,JQuery选择器固然强大,但选择器的主要作用应该是为文档处理服务(也就是本章要学习的内容)。动态更新网页的内容部分(不仅仅是样式),是今后我们开发一个Web应用程序的必然趋势。
我认为,Web应用程序发展的趋势必然分为三种类型:一是以内容为主体的网站(新闻站点、博客站点、门户站点等),这种类型网站特征是页面相对稳定,由服务器端(如:ASP.NET、JSP、PHP)生成即可,AJAX没有太大的用武之地;二是交互为主体的网站(开心网等娱乐性网站),这种网站要求界面丰富、以及各种动态效果,用户的交互十分频繁,需要大量的JavaScript处理用户的操作、并及时更新页面的部分内容,所以需要AJAX技术;三是以应用为主体的网站(企业内部办公、管理等),这类网站同样要求丰富的交互功能,但仅凭JavaScript已经远远不足,需要刚刚开始发展的RIA(如:Silverlight)技术。
本章将详细讲解JQuery框架中操作HTML元素的强大功能,包括动态创建、移除、替换、包装页面中HTML元素,在AJAX应用中,文档处理是必不可少的一部分。
1. 内部添加
JQuery中,在DOM中添加新元素时有两种添加位置,一种称作“内部添加”,将一个JQuery对象中包含的所有HTML元素添加到目标JQuery对象所包含的所有HTML元素中!例如:将<span>hello </span>元素添加到<p></p>中,结果为<p><span>hello</span></p>。
具体的实现方法在本节将详细讲述。
1) append(content)
向JQuery对象中包含的所有HTML元素中追加指定的内容(content),该函数于HTML元素的appendChild(ele)函数功能类似,但append(content)函数允许添加的内容类型更加丰富,更重要的是它是JQuery对象的函数,返回值也只JQuery对象。使用语法:
jQueryObject.append(content)
参数content:要添加的内容。
返回值:JQuery对象。
参数content有三种可选的类型:
l 文本(string):append(text)函数直接将该内容添加到目标元素内。
l HTML 元素:append(htmlElement)函数直接将该元素添加到目标元素内。
l JQuery 对象:append(jQueryObject)函数将JQuery对象中所有的HTML元素添加到目标元素内。
有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
span{
font-style:italic;
}
</style>
……
<div id="container">
<div>View:</div>
<div>Edit:</div>
</div>
要往container中所有的div添加内容,编写如下JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("#container").find("div").append("Hello World.");
});
</script>
执行后HTML结果为:
<div id="container">
<div>View: Hello World.</div>
<div>Edit: Hello World.</div>
</div>
append函数将“Hello World.”直接作为内容添加到了contianer中所有的div元素内(注意:是以追加的方式,即添加到了所有内容的后面)。修改后的JQuery代码如下:
$("#container").find("div").append("<span>Hello World.</span>");
执行后HTML结果为:
<div id="container">
<div>View: <span>Hello World.</span></div>
<div>Edit: <span>Hello World.</span></div>
</div>
在上面代码中,append函数同样将<span>Hello World.</span>作为字符串添加到了container中所有的div元素内。因为在前面的样式表中已经添加了span样式,所以新添加的<span>Hello World.</span>也会自动使用该样式,运行后效果为(图6-1):
图6-1
append(htmlElement)函数和append(JQueryObject)函数本质其实一样,因为JQuery对象中包含的也是HTML元素。这里我们只讲解后者,有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
ul, ol{
margin:10px;
}
.ulStyle{
font-weight:bold;
}
.olStyle{
font-style:italic;
}
</style>
……
<div id="container">
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
<ol>
<li>WinForm</li>
<li>JSP Servlet</li>
</ol>
</div>
要将无序列表(UL)中第二个LI元素添加到有序列表(OL)中,编写如下JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("ol").append($("ul>li:eq(1)"));
});
</script>
执行后HTML结果为:
<div id="container">
<ul>
<li>ASP.NET</li>
</ul>
<ol>
<li>WinForm</li>
<li>JSP Servlet</li>
<li>JavaScript</li>
</ol>
</div>
2) appendTo(content)
将JQuery对象中包含的所有HTML元素添加到指定的内容(content)中,appendTo(content)函数和append(content)函数颠倒了“添加”和“被添加”的顺序,A.append(B)于B.appendTo(A)两者的作用相同。
该函数的使用语法与append函数一样,这里不再详述。
值得注意的是,appendTo(content)函数返回值虽然也是JQuery对象,但返回值是被追加的内容,而不是先前所选定的元素。所以,要继续使用先前所选定的元素,需要盗用end()函数。有如下HTML代码:
<div id="container">
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
<ol>
<li>WinForm</li>
<li>JSP Servlet</li>
</ol>
</div>
要将无序列表(UL)中第二个LI元素添加到有序列表(OL)中,编写如下JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("ul>li:eq(1)").appendTo($("ol"));
});
</script>
执行后HTML结果为:
<div id="container">
<ul>
<li>ASP.NET</li>
</ul>
<ol>
<li>WinForm</li>
<li>JSP Servlet</li>
<li>JavaScript</li>
</ol>
</div>
显而易见,执行结果与append函数相同。
在今后的使用中,我们可以将append函数和appendTo函数根据使用的不同场景随意切换,两者的本质功能没有区别。
3) prepend(content)
首先,append函数和prepend函数语法,包括参数的取值、返回值都是一模一样。所不同的是,prepend函数将content作为前置内容添加。有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
ul, ol{
margin:10px;
}
.ulStyle{
font-weight:bold;
}
.olStyle{
font-style:italic;
}
</style>
……
<div id="container">
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
<ol>
<li>WinForm</li>
<li>JSP Servlet</li>
</ol>
</div>
要将无序列表(UL)中第二个LI元素添加到有序列表(OL)中,编写如下JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("ol").prepend ($("ul>li:eq(1)"));
});
</script>
执行后HTML结果为:
<div id="container">
<ul>
<li>ASP.NET</li>
</ul>
<ol>
<li>JavaScript</li>
<li>WinForm</li>
<li>JSP Servlet</li>
</ol>
</div>
4) prependTo(content)
appendTo函数和prependTo函数语法,包括参数的取值、返回值都是一模一样。所不同的是,prependTo函数将content作为前置内容添加。这里不再详述。
2. 外部添加
JQuery中,在DOM中添加元素的另一种添加位置是“外部添加”,将一个JQuery对象中包含的所有HTML元素添加到目标JQuery对象所包含的所有HTML元素之前或之后!例如:将<span>hello </span>元素添加到<p></p>之后,结果为<p></p><span>hello</span>。
1) after(content)
向JQuery对象中包含的所有HTML元素之后追加指定的内容(content),after(content)函数允许添加的内容类型十分丰富。使用语法:
jQueryObject.after(content)
参数content:要添加的内容。
返回值:JQuery对象。
参数content有三种可选的类型:
l 文本(string):after (text)函数直接将该内容添加到目标元素之后。
l HTML 元素:after (htmlElement)函数直接将该元素添加到目标元素之后。
l JQuery 对象:after (jQueryObject)函数将JQuery对象中所有的HTML元素添加到目标元素之后。
有如下HTML代码:
<p>I would like to say: </p>
JQuery代码:
$("p").after("<b>Hello</b>");
执行结果:
<p>I would like to say: </p><b>Hello</b>
上述代码直接使用字符串作为参数,当然也可以使用HTML元素或JQuery对象(两者没有本质的区别,JQuery对象中包含的也是HTML元素)。有如下HTML代码:
<b id="foo">Hello</b><p>I would like to say: </p>
JQuery代码:
$("p").after( $("#foo") );
执行结果:
<p>I would like to say: </p><b id="foo">Hello</b>
after函数除了追加元素的位置与append不同,使用语法同append完全一样,请各位读者自行对比。
2) insertAfter (content)
after(content)函数与insertAfter(content)函数的关系,就如同append(content)函数和appendTo(content)函数的关系一样。A.after(B)完全等价于B.insertAfter(A),都是将B追加到A之后。两个函数返回值都是JQuery对象,都是包装A的JQuery对象。对于B.insertAfter(A),如果希望继续使用B,需要使用end()函数,如:B.insertAfter(A).end()。
关于insertAfter函数的具体用法,这里不再详述。
3) before(content)
after(content)函数和before(content)函数语法、参数取值、返回值也都是一样的,所不同的是,before(content)函数将content添加到JQuery对象中所有HTML元素之前,除此之外,大家使用时不用去区别。有如下HTML代码:
<p>I would like to say: </p>
JQuery代码:
$("p").before("<b>Hello</b>");
执行结果:
<b>Hello</b><p>I would like to say: </p>
上述代码直接使用字符串作为参数,当然也可以使用HTML元素或JQuery对象(两者没有本质的区别,JQuery对象中包含的也是HTML元素)。有如下HTML代码:
<p>I would like to say: </p><b id="foo">Hello</b>
JQuery代码:
$("p").before( $("#foo") );
执行结果:
<b id="foo">Hello</b><p>I would like to say: </p>
4) insterBefore(content)
before (content)函数与insertBefore(content)函数的关系,就如同prepend(content)函数和prependTo(content)函数的关系一样。A. before (B)完全等价于B. insertBefore (A),都是将B追加到A之前。两个函数返回值都是JQuery对象,都是包装A的JQuery对象。对于B. insertBefore (A),如果希望继续使用B,需要使用end()函数,如:B. insertBefore (A).end()。
关于insertBefore函数的具体用法,这里不再详述。
3. 包装
前面我们详细讲解了append、after等函数,这些函数的作用都是将内容(content)加入到DOM中。有些时候,我们不需要在页面中添加内容,但希望在指定的元素上面添加一些标签,从而改变DOM的结构,这就是本节课要讲到得包装 ,如:<span>Hello</span>,可以使用p来包装整个span标签,<p><span>Hello</span></p>,也可以使用b来包装span中的内容,<span><b>Hello</b></span>。
1) wrap(html)
使用指定的内容(content)包装JQuery对象中每一个HTML元素(即:每一个HTML元素都有一个包装,这点与wrapAll不同)。使用语法:
JQueryObject.wrap(content)
参数content:用来包装每一个HTML元素。
返回值:JQuery对象。
参数content有三种可选的类型:
l html:直接使用该参数(html字符串)所表示的元素包装。
l HTML元素:直接使用该元素包装。
l JQuery 对象:本质于HTML元素相同(建议使用HTML元素,可以通过JQueryObject.get(index)函数获取JQuery对象中指定的HTML元素)。
有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
ul{
margin:10px;
}
.wrapper{
font-style:italic;
font-size:1.5em;
}
</style>
……
<div id="container">
<div class="wrapper"></div>
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
</div>
要使用<div class=”wrapper”></div>包装所有LI元素,JQuery代码如下:
<script type="text/javascript">
jQuery(function() {
$("li").wrap($(".wrapper").get(0));
});
</script>
执行后HTML结果为:
<div id="container">
<div class="wrapper"></div>
<ul>
<div class="wrapper"><li>ASP.NET</li></div>
<div class="wrapper"><li>JavaScript</li></div>
</ul>
</div>
也可是将上述JQuery代码改为:
$("li").wrap("<div class='wrapper'></div>");
执行结果没有任何变化,运行后如下图6-2:
图6-2
2) wrapAll(content)
wrap(content)函数会包装JQuery对象中的每一个HTML元素,如果JQuery对象中有N个元素,就需要N个content进行包装。
wrapAll(content)函数用来包装JQuery对象中所有的HTML元素,也就是使用一个content放在所有的HTML元素外面!使用语法:
JQueryObject.wrapAll(content)
参数content:用来包装所有HTML元素。
返回值:JQuery对象。
参数content有三种可选的类型:
l html:直接使用该参数(html字符串)所表示的元素包装。
l HTML元素:直接使用该元素包装。
l JQuery 对象:本质于HTML元素相同(建议使用HTML元素,可以通过JQueryObject.get(index)函数获取JQuery对象中指定的HTML元素)。
有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
ul{
margin:10px;
}
.wrapper{
font-style:italic;
font-size:1.5em;
}
</style>
……
<div id="container">
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
</div>
使用<div class=”wrapper”></div>包装所有的LI元素,JQuery代码如下:
<script type="text/javascript">
jQuery(function() {
$("li").wrapAll("<div class='wrapper'></div>");
});
</script>
执行后HTML结果如下:
<div id="container">
<ul>
<div class=”wrapper”>
<li>ASP.NET</li>
<li>JavaScript</li>
</div>
</ul>
</div>
运行后如下图6-3:
图6-3
3) wrapInner(content)
wrap(content)函数包装了整个HTML元素,在元素的外面加了一个标签,这有时候会破坏原始DOM的结构,就如上面例子执行后的结果:
<div id="container">
<ul>
<div class="wrapper"><li>ASP.NET</li></div>
<div class="wrapper"><li>JavaScript</li></div>
</ul>
</div>
很显然,这样的代码是不好的。如果使用wrapInner(content)函数包装,将得到如下的结果:
<div id="container">
<ul>
<li><div class="wrapper">ASP.NET</div></li>
<li><div class="wrapper">JavaScript</div></li>
</ul>
</div>
这就是wrap和wrapInner的区别。
wrapInner(content)函数用来包装JQuery对象中每一个元素的内容部分,正如上面代码所示!使用语法:
JQueryObject.wrapInner(content)
参数content:用来包装每一个HTML元素的内容。
返回值:JQuery对象。
参数content有三种可选的类型:
l html:直接使用该参数(html字符串)所表示的元素包装。
l HTML元素:直接使用该元素包装。
l JQuery 对象:本质于HTML元素相同(建议使用HTML元素,可以通过JQueryObject.get(index)函数获取JQuery对象中指定的HTML元素)。
有如下HTML代码:
<style type="text/css">
#container{
width:600px;
}
ul{
margin:10px;
}
.wrapper{
font-style:italic;
font-size:1.5em;
}
</style>
……
<div id="container">
<ul>
<li>ASP.NET</li>
<li>JavaScript</li>
</ul>
</div>
现在要使用<div class=”wrapper”></div>包装所有列表项(LI)中,包含字符串“NET”的列表项的内容,编写JQuey代码如下:
<script type="text/javascript">
jQuery(function() {
$("li:contains(NET)").wrapInner("<div class='wrapper'></div>");
});
</script>
执行后HTML结果为:
<div id="container">
<ul>
<li><div class="wrapper">ASP.NET</div></li>
<li>JavaScript</li>
</ul>
</div>
运行效果如下图6-4:
图6-4
4. 替换
获取到也面元素后(通常是得到了包装它们的JQuery对象),除了添加、包装外,还可以执行替换和删除。其实,只要是数据操作,不管针对的数据是什么格式,都离不开这四种操作:增、删、改、查,HTML元素数据也是如此。
本节详细介绍元素的替换,下一节将介绍元素的删除。
1) replaceWith(content)
将JQuery对象中每一个HTML元素使用指定的内容(content)替换(注意:如果JQuery对象中有N个HTML元素,将使用指定的content替换N次)。使用语法:
JQueryObject.replaceWith(content)
参数content:用来替换HTML元素的内容。
返回值:JQuery对象。
参数content有三种取值类型:
字符串(String):使用该String直接替换
HTML元素:使用该元素直接替换
JQuery对象:使用JQuery对象中的HTML元素替换(本质上与HTML元素替换一样)。
有如下HTML代码:
<div id="container">
<p>Hello</p>
<p>World</p>
<p>Welcome</p>
</div>
JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("p").replaceWith("<b>New Content. </b>");
});
</script>
执行后HTML结果为:
<div id="container">
<b>New Content. </b>
<b>New Content. </b>
<b>New Content. </b>
</div>
2) replaceAll(content)
replaceAll(selector)函数和replaceWith(content)的关系,与前面讲过的append(content)函数和appendTo(content)函数一样,也是主动和被动不同的关系。A.replaceWith(B)和B.replaceAll(A)的作用一样,都是用B来替A。返回的都是包含被替换后的JQuery对象。使用语法:
JQueryObject.replaceAll(content)
参数content:被替换的HTML元素
返回值:JQuery对象。
参数content有两种可选类型:
选择器(selector):匹配被替换的HTML元素。
JQuery对象:包装被替换的HTML元素。
有如下HTML代码:
<div id="container">
<p>Hello</p>
<p>World</p>
<p>Welcome</p>
</div>
JQuery代码:
<script type="text/javascript">
jQuery(function() {
$("<b>New Content. </b> ").replaceAll("p");
// 或 $("<b>New Content. </b> ").replaceAll($("p"));
});
</script>
执行后HTML结果为:
<div id="container">
<b>New Content. </b>
<b>New Content. </b>
<b>New Content. </b>
</div>
4. 删除
用来删除DOM中的元素或内容。
1) empty()
删除JQuery对象中每一个HTML元素的子元素,就是让JQuery对象中的每一个HTML元素都变成一个空元素。使用语法:
JQueryObject.empty();
返回值:JQuery对象。
有如下HTML代码:
<div id="container">
<p>Hello</p>
<p><span>World</span></p>
<p>Welcome</p>
</div>
JQuery代码如下:
<script type="text/javascript">
jQuery(function() {
$("#container>p").empty();
});
</script>
执行后HTML代码为:
<div id="container">
<p> </p>
<p></p>
<p> </p>
</div>
2) remove([selector])
将JQuery对象中被指定的(如果参数为空,则表示所有)的HTML元素从DOM(当前页面)中删除,但并不会从当前JQuery对象中删除,也就是说,该JQuery对象中的元素可以被接着使用。使用语法:
JQueryObject.remove([selector])
参数selector:标准的选择器,匹配要被删除的HTML元素。
返回值:JQuery对象。
有如下HTML代码:
<div id="container">
<p>Hello</p>
<p class="del">World</p>
<p>Welcome</p>
</div>
JQuery代码如下:
<script type="text/javascript">
jQuery(function() {
$("#container>p").remove(".del");
});
</script>
执行后HTML代码为:
<div id="container">
<p>Hello</p>
<p>Welcome</p>
</div>
如果remove函数不带参数,则执行后的HTML代码为:
<div id=”container”>
</div>
6. 元素复制
提到“克隆”,相信大家都不陌生,是面向对象编程中复制对象的一种常用方法。在JQuery中,JQuery对象也支持“克隆”方法。
1) clone()
赋值JQuery对象中HTML元素的副本,封装成JQuery对象后返回,这些副本可以被添加在页面上的其它位置。使用语法:
JQueryObject.clone()
返回值:JQuery对象,包装了被复制出的新HTML元素。
该函数会复制HTML元素的所有内容各部分,但不会复制所注册的事件。有如下HTML代码:
<div id="container">
<button οnclick="copy();">复制一份</button>
<div class="item-style">
<div class="header">clone()</div>
<div class="content hide">
克隆匹配的DOM元素并且选中这些克隆的副本。
</div>
</div>
</div>
当点击“复制一份”的按钮时,将<div class=”item-style”>……</div>元素(连同子元素)复制一份,并将新的Div元素添加到container中,JQuery代码如下:
<script type="text/javascript">
jQuery(function() {
$(".item-style .header").click(function() {
$(this).next().toggleClass("hide");
});
});
function copy() {
$(".item-style:first").clone().appendTo("#container");
}
</script>
在浏览器中打开点“复制一份”按钮两次,效果如下图6-5:
图6-5
点击这两个新行时,并不会展开,因为clone()函数并没有复制事件的注册。
2) clone(true)
除具有clone()函数的所有功能外,还会复制HTML元素的事件!这里同样使用上面得HTML代码,将JQuery代码该为:
<script type="text/javascript">
jQuery(function() {
$(".item-style .header").click(function() {
$(this).next().toggleClass("hide");
});
});
function copy() {
$(".item-style:first").clone(true).appendTo("#container");
}
</script>
运行之后结果如下图6-6:
图6-6