[Javascript]深入浅出tbody

做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 data</td></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;i<trNode.length;i++){
        rows[i] = trNode[i];
    }

    if(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;i<rows.length;i++){
        var 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 Name</td>
            <td>Price</td>
            <td>Saler</td>
            <td>Province</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>T-shirt</td>
            <td>338.00</td>
            <td>Mike</td>
            <td>GuangDong</td>
        </tr>
        <tr>
            <td>Watch</td>
            <td>228.00</td>
            <td>Daisy</td>
            <td>Hebei</td>
        </tr>
        <tr>
            <td>Camera</td>
            <td>1000.00</td>
            <td>Betty</td>
            <td>Zhejiang</td>
        </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>

[排序前]
这里写图片描述

[按商品名排序]
这里写图片描述

[按价格排序]
这里写图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值