做Web开发,生成表格几乎是家常便饭,我们印象中的表格代码通常是这样的:
<table>
<tr><td>td>tr>
<tr><td>td>tr>
<tr><td>td>tr>
table>
但是,你会发现有些网站的Table结构是这样的:
<table>
<thead>
<tr><td>td>tr>
thead>
<tbody>
<tr><td>td>tr>
<tr><td>td>tr>
<tr><td>td>tr>
tbody>
table>
thead和tbody是什么鬼?既然前面一种Table结构已经可以显示出表格,为什么还要设计出后面那种Table结构?
存在即为合理,既然主流浏览器都支持这种格式,肯定有它用武之地。关键是什么时候需要用到这种Table结构。
无缘无故多写个thead和tbody标签,虽然就增加了那么四行代码,对于容不下一点冗余代码的优秀程序员(不好意思说是本人)来说,心里也是千百个不愿意的。
好了,我们设想一下,如果我们需要取到淘宝网的商品信息,再用表格显示出来,这个时候应该怎么办?
有人说了,还是用第一种Table格式啊,结构简单清晰。
没错,光是显示数据的话,采用第一种格式无疑有代码量和易读性上的优势。
但是如果我们增加一点需求,比如对商品名称进行排序。
你会说,很简单啊,让淘宝在后台排好序再把数据传过来就好了。如果淘宝是我们开的,当然想让它后台怎么排序就怎么排序。假定淘宝说“我给你的数据和给别人的数据都是一样的,别人也没你这么多要求,我们忙得很,没空帮你排序!”,我们该怎么办呢?这个时候也只能靠我们自己了,在前台用Javascript对Table里的数据进行排序。
我们首先能想到的能动态修改页面元素的属性是innerHTML属性,很遗憾,微软是这么告诉我们的:
The innerHTML property is read-only on the col, colGroup, frameSet, html, head, style, table, tBody, tFoot, tHead, title, and tr objects.
参考链接:https://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx
What?IE浏览器下Table元素的innerHTML是只读的,不能修改?也就是不能用用类似以下语句改变Table内容:
document.getElementsByTagName("table")[0].innerHTML = "<table><tr><td>changed datatd>tr>table>";
好吧,祭出我们的百度神器,瞬间几百篇讲解怎么随心所欲更改Table结构的文章出现在眼前。
但是,你永远不要相信这些所谓大神们写的代码,分分钟他们也是拷贝的其他人的代码,并且自己并没有运行成功就放到网上去,以增加自己在网络上的存在感,获取那么一点点傲立华山之巅的虚荣。
比如下面这段代码:
var t=document.getElementById("test");
var tr=document.createElement("tr");
var td=doucment.createElement("td");
td.innerHTML="数据";
tr.appendChild(td);
t.appendChild(tr);
好了,不用费劲了,无论你执行多少遍,这段代码都不会起作用,尼玛代码第四行的document写成了doucment,可以执行才见鬼了。
强烈安抚住心中奔腾的一万只草泥马,把doucment改回document,代码还是无效。我不知道这位大神是如何有自信把这段代码拷给提问者使用,而这位提问者还给这位大神点了个赞。。。
好了,以上都是废话,我们来看真正可以执行的代码(绝对经本人测试通过):
var table = document.getElementById("productList");
var tr=document.createElement("tr");
var td=document.createElement("td");
var tbody = document.createElement("tbody");
td.innerHTML="test";
tr.appendChild(td);
tbody.appendChild(tr);
table.appendChild(tbody);
对比两段代码,你可以看出,其实后面那段代码仅仅多增加了个tbody的子元素。
或者说,浏览器支持的DOM操作,table的子元素必须是tbody,tbody下面才是tr子元素。
你直接在table下面直接添加tr子元素,浏览器肯定是拒绝的,一切要按规矩来。
明白了这层道理,我们要增加删除Table的子元素就简单多了,无非是利用好下面几个方法。
createElement()方法:生成一个子元素。
appendChild()方法:在父元素下面增加一个子元素。
removeChild()方法:在父元素下面删除一个子元素。
回到我们上面的需求,对淘宝网取到的数据进行排序后显示,还要利用到Javascipt的一个sort()方法,具体怎么使用请自行百度,当然且百度且珍惜,对百度到的代码要小心求证。
完整的代码如下,实现了按“商品名”排序和按“价格”排序,大家可以自己试验更多的排序方法:
<html>
<style type="text/css">
table {
border-collapse:collapse;
border:none;
}
td{
border:solid #000000 1px;
}
.title {
background-color:#FFFF00;
}
style>
<script language=JavaScript src="js/jquery.min.js" type=text/javascript>script>
<script>
function doSort(type){
var table = document.getElementById("productList");
var tbodyNode = table.getElementsByTagName("tbody")[0];
var trNode = tbodyNode.getElementsByTagName("tr");
var rows = new Array(trNode.length);
for(var i=0;iif (type == "name"){
rows.sort(sortByProductName);
}else if(type == "price"){
rows.sort(sortByPrice);
}else{
//other sort type
}
table.removeChild(tbodyNode);
var newTbody = document.createElement("tbody");
for(var i=0;ivar newTrNode = document.createElement("tr");
newTrNode = rows[i];
newTbody.appendChild(newTrNode);
}
table.appendChild(newTbody);
}
function sortByProductName(a,b){
var productNameA = a.getElementsByTagName('td')[0].innerHTML;
var productNameB = b.getElementsByTagName('td')[0].innerHTML;
if (productNameA > productNameB){
return 1;
}else {
return -1;
}
}
function sortByPrice(a,b){
var priceA = a.getElementsByTagName('td')[1].innerHTML;
var priceB = b.getElementsByTagName('td')[1].innerHTML;
if (eval(priceA) > eval(priceB)){
return 1;
}else {
return -1;
}
}
script>
<body>
<table id="productList">
<thead class="title">
<tr>
<td>Product Nametd>
<td>Pricetd>
<td>Salertd>
<td>Provincetd>
tr>
thead>
<tbody>
<tr>
<td>T-shirttd>
<td>338.00td>
<td>Miketd>
<td>GuangDongtd>
tr>
<tr>
<td>Watchtd>
<td>228.00td>
<td>Daisytd>
<td>Hebeitd>
tr>
<tr>
<td>Cameratd>
<td>1000.00td>
<td>Bettytd>
<td>Zhejiangtd>
tr>
tbody>
table>
<br>
<input type="button" value="Sort By Product Name" onclick="doSort('name')" />
<input type="button" value="Sort By Price" onclick="doSort('price')" />
body>
html>