EasyTable2.0 功能更加强大,bug全面修复的html table插件!

最近整理和修复了1.0的全部bug,并且给2.0添加了不少新功能。由于语法上有些修正,所以我重新写了一个非常详细的demo.html在文档里面,这里直接贴出(由于添加了新的功能,et的2.0的压缩版本已经达到了20k的体积了,虽然略显大一些,但是我相信从功能上来讲觉得是划得来的。):

<html>
<head>
    <title></title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <p style="height: 50px; line-height: 50px; text-align: center; font-family: 黑体; font-size: 22px;">EasyTable全教程</p>
    <div id="target"></div>
</body>
<script type="text/javascript" src="EasyTable.js"></script>
<script type="text/javascript">
    /***   解除注释即可查看运行情况,建议使用火狐浏览器的firebug一边调试一边查看,注意每一次只查看一条,一次性全部查看会导致et.table0错误。  ***/

    /*插件支持浏览器:所有现代浏览器,ie8、9。但需要注意,ie浏览器的语法非常严(qi)谨(pa),需要特别小心,另外ie有时候不支持margin:0 auto等类型的语法糖,直接使用会导致错误。同时ie不能在object或数组中存在多余的逗号,所有方法结尾都要加上分号。*/

    /***** 友情提醒:珍爱生命,远离IE!! *****/

    //1.用EasyTable插件创建一个table表格。/
    //我们需要利用EasyTable的draw方法,并传入一个Object,该Object的targetId属性绑定一个在body中的对象的id,我们的table就会在此id下创建。
    //EasyTable.draw({ targetId:"target" });

    //2.如果不采用targetId属性直接检索页面元素的话,也可以用target属性直接传入一个页面元素。
    //EasyTable.draw({
    //    target: document.getElementById("target")
    //});
    //
    //如果使用jquery则是:
    //EasyTable.draw({
    //    target: $("#target")[0]
    //});

    //3.但请注意,如果以上两个属性同时出现,那么只会使用targetId属性的绑定。
    //EasyTable.draw({
    //    target: document.getElementById("target"),
    //    targetId: "target2"
    //});

    //4.由于EasyTable.draw()的写法略显罗嗦,所以用户可以直接用et.draw()代替,另外,也可以用:var 你设定的名字 = et;来自定义EasyTable的名字。
    //et.draw({ targetId: "target" });
    //var myName = et;
    //myName.draw({ targetId: "target2" });

    //5.EasyTable.draw()(以下简称et.draw())传入数据非常简单,只需要在data属性里传入一个数组即可,默认情况下et是三列,数据将自动按照每行三个依次排列下去,多余地方由空的td补全。
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5]
    //});

    //6.用户可以自定义列数,使用col属性:(col属性并不是必须的,但是多数情况下我们会自定义列数。)
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5],
    //    col:2
    //});

    //7.用户可以自定义行数,使用row属性:(但注意,如果data的数组长度大于用户给定的行列数的乘积,那么et会自动生成新的tr进行补全,而不是抛弃放不下的数据。row属性并不是必须的,大部分情况下都不需要用到该属性。)
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9],
    //    col: 4,
    //    row: 2
    //});

    //8.用户可以设定tableStyle属性、trStyle属性和tdStyle属性来设定你的table、tr和td的相关style。即使用户不进行任何设置,默认情况下,table也会加上两个style:width:100%和border-collapse:collapse。通常情况下,trStyle和tdStyle只需要用一个就够了。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    trStyle: "height:40px;color:white;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;",
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //9.在使用table时,经常需要处理的情况就是列之间的宽度的平分,这里我们可以使用deuce属性,只需要设置为true。那么table就会自动帮你设置列的宽度平分。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //10.每次使用draw方法,生成的table都有一个共同的class:EasyTable。同时第一个的id为EasyTable0,第二个是EasyTable1,以此类推。同时也会生成一个对应的et属性。比如,et.draw({ ..... }); 使用et.table0 等价于 document.getElementById("EasyTable0")。

    //11.每次生成draw方法,如果使用普通方法清除掉运行过程中的table的话,该序列号并不会被回收。即:假设你清除了id为EasyTable1的table后再执行et.draw()方法,下次生成的是id为EasyTable2。为了解决这个问题,可以使用destroy()方法。et.destroy(et.table1);那么下次你再使用draw方法时,得到的新的table的id还是EasyTable1。这样的话et.table1属性访问到的就是你的新table,而不会变成undefined。
    //destroy()方法允许传入多个table,一次性销毁多个table并回收多个序列号。如:et.destroy(et.table0,document.getElementById("EasyTable1"));
    //destroy()方法也可以不传入任何参数。那么将会销毁所有的table。请慎用:et.destroy();

    //12.et.draw()可以为指定的格子进行colspan和rowspan的设置,并且可以一次性设置多个。(坐标的第一个表示某一行tr,从0开始数起,坐标的第二个值表示该tr中的某一个td,也是从0开始数起。"(1,0)"即表示第二行的第一个。需要注意的是,这两个属性不能与下面的添加行、列等功能配合,并且该功能容易造成数据的难以理解,不建议大规模使用。)具体格式如下:
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    colspan: { "(0,0)": 2,"(0,1)":2 },
    //    rowspan: { "(0,0)": 3 },
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //13.et.draw()拥有竖向排列数据的功能。使用type属性并设置为vertical即可。但是该功能对于后面要介绍到的addTd功能有一个小冲突。后面会详述。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    type: "vertical",
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
    //    col: 4
    //});

    //14.et.draw()可以对原有的table进行扩展,即:appendCol、appendRow方法:("0":2 的意思是在第1列的右边插入2列,"1":4 的意思是在第二行的下面插入四行。)
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    appendCol: { "0": 2, "1": 3 },
    //    appendRow: { "1": 4 },
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //15.同理,也有 prependCol 和 prependRow 方法,只是插入的位置变成左边和上边。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    prependCol: { "0": 2, "1": 3 },
    //    prependRow: { "1": 4 },
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //16.使用colStyle 和 rowStyle 可以对指定的列、行添加style。如果两者同时存在于一个td上,则col覆盖row。格式为:(index)[style内容]
    //注意:rowStyle是直接设置在tr上的style,如果使用了tdStyle,那么rowStyle可能会被覆盖。后面可以用style解决该问题。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    //tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    colStyle: "(0)[background-color:red;]",
    //    rowStyle: "(0)[background-color:yellow]",
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //17.上面介绍了appendCol 和 prependCol,以及 appendRow 和 prependRow。下面介绍emtpyCol 和 emptyRow。作用是清空指定行、列中的数据。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    emptyCol: 1,//清除第二列的数据
    //    emptyRow: [1, 2],//清除第二行和第三行的数据,这两个方法都可以传入一个数字或者一个数字数组。
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //18. removeCol 和 removeRow 方法与上面的用法类似,作用是彻底删除指定的行、列,而不仅仅是清空其中的数据。
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",//在ie浏览器中,由于对margin:0 auto的支持性欠佳,所以最好使用margin-left:5%令其居中。
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    removeCol: 1,//删除第二列
    //    removeRow: [1, 2],//删除第二行和第三行,这两个方法都可以传入一个数字或者一个数字数组。
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //19.et.draw()可以使用id属性设置某一行tr的id,也可以设置某一个td的id。但请慎用该方法,因为et有些style是通过id实现的,如非必要,尽可能不要修改tr或者td默认的id。
    //et.draw({
    //    target: document.getElementById("target"),
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    //id: "(0)[xiugai]",//这里的意思是将第一行的tr的id改成:xiugai,可以传入一个字符串,也可以传入一个数组,20中的其他类型也一样。
    //    id:["(0,0)[xiugai1]","(0,1)[xiugai2]"],//(0,0)表示第一行第一个td,(0,1)表示第一行第二个td,以此类推。
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //20.et中也可以使用cls属性修改class、style属性修改style、html属性修改内部文字,用法和id一致。
    //et中的id、style、class、html等方法都不推荐经常或者大量地使用。它们的作用仅仅是处理项目中临时性或突然性出现的对局部更改的需求。
    //et.draw({
    //    target: document.getElementById("target"),
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    cls: "(0)[newClass]",//注意:class和id不同,用该方法创建的class并不会覆盖原来的class,而是增加进去。因为一个元素可以有多个class。另外由于“class”是js中的关键词,在部分浏览器中直接写为一个object的属性会报错。为了兼容性的考虑,所以将class写成cls。
    //    style: "(1,0)[background-color:red]",//style方法和class方法一样,如果目标对象已有一定的style,则不覆盖原有的style,而是采取追加的方式插入新的style。
    //    html: "(2,0)[<td></td><td></td><td></td><td></td>]",//特别注意:请尽量不要直接修改tr的innerHTML。在ie浏览器中,tr的innerHTML是只读的,无法修改(直接修改将导致错误)。如果要修改,请修改td的html。
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //21.et.draw()中的attr属性可以为元素添加attr,通常用于对元素添加onclick事件:
    //et.draw({
    //    target: document.getElementById("target"),
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    attr: { "onclick": "(0)[alert(1)]", "onmouseover": ["(1,0)[this.style.backgroundColor='yellow']", "(1,1)[this.style.backgroundColor='green']"], "onmouseleave": ["(1,0)[this.style.backgroundColor='deepskyblue']", "(1,1)[this.style.backgroundColor='deepskyblue']"] },//注意传入的是对象,不是数组格式。要同时作用于多个则在一个对象属性中传入数组。并且在ie浏览器中,以attr属性的形式绑定的事件都是无法执行的,所以如果需要考虑ie浏览器的话,需要用我们后面介绍到的addEvent方法。
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4
    //});

    //22.et.draw()中的最后一个属性,callback,回调操作,第一个参数是table元素本身,第二个元素是table的id,用户可以根据实际需要来使用:
    //et.draw({
    //    target: document.getElementById("target"),
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    //    col: 4,
    //    callback: function (table,tableid) {
    //        table.style.marginTop = "100px";
    //        alert(table == document.getElementById(tableid));
    //    }
    //});

    //上面已经介绍完了draw()方法,在实际应用中,动态生成表格通常是需要根据网页请求到的数据动态添加tr和td。因此,下面我们将介绍addTr()和addTd()方法。
    //23.et.addTr()方法的target必须是一个table,data是数组,内容是td中的innerHTML。
    //et.draw({
    //    target: document.getElementById("target"),
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    data: [1, 2, 3],
    //    col: 3
    //});
    //et.addTr({
    //    target: et.table0,//这里利用的是条目10中提到的方法。
    //    data:["新增内容1","新增内容2","新增内容3"]
    //});

    //24.et.addTr()中也支持id、class、style、attr方法,根据传入的是字符串或者数组来判断作用于tr还是td。
    //var tb;
    //et.draw({
    //    targetId: "target",
    //    tableStyle: "width:90%;margin:0 auto;text-align:center;margin-left:5%",
    //    tdStyle: "background-color:deepskyblue;border:1px solid #7f7f7f;height:40px;",
    //    deuce: true,
    //    //data: [1, 2, 3],在没有data的情况下,et也会默认生成一行空的tr。
    //    col: 3,
    //    callback: function (table) {
    //        tb = table;
    //    }
    //});
    //et.addTr({
    //    target: tb,//这里我们介绍另一种方法获取目标table,就是用一个变量在上面的callback中将table记录下来。
    //    data: ["新增内容1", "新增内容2", "新增内容3"],
    //    id: "xiugai",//作用于tr
    //    cls: "newClass",//作用于tr
    //    style: "font-family:隶书",//作用于tr
    //    attr: { "onclick": "alert(1)" }//老惯例,这种onclick的事件设置方法在ie浏览器是无效的。
    //});
    //et.addTr({
    //    target: tb,
    //    data: ["新增内容4", "新增内容5", "新增内容6"],
    //    id: ["xiugai1", "xiugai2", "xiugai3"],//作用于三个td。
    //    cls: ["new1", "", "new3"],//作用于第一个td和第三个td,第二个td相当于没有添加新的class。
    //    style: ["background-color:yellow", "background-color:red", "background-color:blue"],//分别加上三种不同的背景色。
    //    attr: { "onclick": "alert(1)", "onmouseover": ["", "this.style.backgroundColor='deepskyblue'"], "onmouseleave": ["", "this.style.backgroundColor='red'"] }//作用于第一个和第二个td。
    //});

    //25.addTr()中有toggleStyle和toggleAttr方法,作用于tr。意思是在生成的tr中,如果第一个tr得到了style/attr,那么下一个就不会得到该style/attr,而再下一个又会得到。以此类推。常见的例子就是tr的隔行变色:
    //et.draw({
    //    targetId: "target",
    //    tdStyle: "border:1px solid black;height:30px;text-align:center;",
    //    callback: function (table) {
    //        for (var i = 0; i < 10; i++) {
    //            et.addTr({
    //                target: table,
    //                data: ["第" + (i + 1) + "行-第一个", "第" + (i + 1) + "行-第二个", "第" + (i + 1) + "行-第三个"],
    //                toggleStyle: "background-color:#d9d9d9;",
    //                toggleAttr: { "onclick": "alert(" + (i + 1) + ")" }//在ie浏览器无法观察到其点击事件。
    //            });
    //        }
    //    }
    //});

    //26.上面的例子中,toggleStyle和toggleAttr中都是从第一行(也就是第一个tr)开始的,如果想从第二个(即偶数行开始),需要进行以下设置:
    //在table的callback中加上:table.trToggleStyle = false;table.trToggleAttr = false;
    //et.draw({
    //    targetId: "target",
    //    tdStyle: "border:1px solid black;height:30px;text-align:center;",
    //    callback: function (table) {
    //        table.trToggleStyle = false;table.trToggleAttr = false;//就是这一行
    //        for (var i = 0; i < 10; i++) {
    //            et.addTr({
    //                target: table,
    //                data: ["第" + (i + 1) + "行-第一个", "第" + (i + 1) + "行-第二个", "第" + (i + 1) + "行-第三个"],
    //                toggleStyle: "background-color:#d9d9d9;",
    //                toggleAttr: { "onclick": "alert(" + (i + 1) + ")" }//在ie浏览器无法观察到其点击事件。
    //            });
    //        }
    //    }
    //});

    //27.addTr()方法也有callback。第一个参数是tr自己,第二个参数是它以下的td的数组集合,请注意是数组。
    //et.draw({
    //    targetId: "target",
    //    tdStyle: "border:1px solid black;height:30px;text-align:center;"//没有设置col(列数)时则col为3。
    //});
    //et.addTr({
    //    target: et.table0,
    //    callback: function (tr, tds) {
    //        tr.style.backgroundColor = "green";
    //        var arr = ["测试1", "测试2", "测试3"];
    //        for (var i = 0; i < tds.length; i++) {
    //            tds[i].innerHTML = arr[i];
    //            tds[i].style.color = "white";
    //        }
    //    }
    //});

    //28.addTd()方法与addTr()方法非常类似,但需要注意,如果用户创建的table中存在空白格,则addTd()方法会自动将内容追加到空白格中。但这些空白格对appendCol、appendRow、prependCol和prependRow生成的空白格无效。
    //et.draw({
    //    targetId: "target",
    //    tdStyle: "border:1px solid black;height:30px;text-align:center;",
    //    data: [1, 2],
    //    deuce: true,
    //    col: 6,
    //    //请通过注释和解除注释下面的callback来查看效果。
    //    callback: function (table) {
    //        for (var i = 0; i < 6; i++) {
    //            et.addTd({
    //                target: table,
    //                data: "新增内容" + (i + 1),//由于每次只插入一个td,因此插入的data只能是一个字符串,而不能是数组。
    //                id: "xiugai" + (i + 1),//id传入的是字符串。
    //                cls: "newClass" + (i + 1),//class同上。
    //                style: "background-color:deepskyblue",//style同上。
    //                attr: { "onclick": "alert(" + (i + 1) + ")" }//attr类比addTr()中的attr。
    //            });
    //        }
    //    }
    //});

    //29.addTd()中的callback返回的是该td。同样也有toggleStyle和toggleAttr方法:
    //et.draw({
    //    targetId: "target",
    //    tdStyle: "border:1px solid black;height:30px;text-align:center;",
    //    data: [1, 2],
    //    deuce: true,
    //    col: 6,
    //    callback: function (table) {
    //        table.tdToggleStyle = false; table.tdToggleAttr = false;//这一行的两句表示toggle将从第二个开始,和上面的tr的用法是一样的。只是将tr改成了td。
    //        for (var i = 0; i < 6; i++) {
    //            et.addTd({
    //                target: table,
    //                data: "新增内容" + (i + 1),
    //                style: "background-color:yellow;",
    //                toggleStyle: "background-color:deepskyblue;",//注意,在ie浏览器中,如果一个dom对象的style里同时拥有两个相同的设置,(比如都是background-color),那么ie会同时删除两个,而不是保留第二个!也就是说,这样做的结果是两个style属性一起消失!如果用户想要兼容垃圾到不能再垃圾的ie浏览器,需要在for循环中设置style如下:
    //                //style:"background-color:"+( i%2 == 0 ? "yellow" : "deepskyblue" ),
    //                toggleAttr: { "onclick": "alert(" + (i + 1) + ")" },
    //                callback: function (td) {
    //                    td.style.fontFamily = '隶书';
    //                }
    //            });
    //        }
    //    }
    //});

    //30.当table的type为vertical时,如果addTd()方法填满了指定格子数(也就是行与列的乘积),则又会变成横向排列了,示例如下:
    //et.draw({
    //    targetId: "target",
    //    col: 6,
    //    row: 6,
    //    type:"vertical",
    //    deuce: true,
    //    callback: function (table) {
    //        console.log(table.row + " " + table.col)
    //        for (var i = 0; i < 40; i++) {
    //            et.addTd({
    //                target: table,
    //                data: i,
    //                style:"background-color:deepskyblue;height:40px;border:1px solid #7f7f7f;text-align:center;"
    //            });
    //        }
    //    }
    //});
    //在浏览器中查看会发现,超过35的36、37、38、39自动以横向的形式排列在最下方的一行上。造成这种现象的原因是et是以col乘以row的格子进行数据排列的,当格子不够时只能以横向并入。为了解决这个问题,最好是在运行前先通过其他方法判断所需的行数和列数,然后再设置好行列数,然后再执行draw({type:"vertical"});

    //31.上面已经介绍完了et中最重要的三个方法:draw() 、 addTr() 、 addTd() 以及destroy(),下面介绍hook方法:
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5, 6, 7],
    //    deuce:true,
    //    tdStyle: "background-color:deepskyblue;border:1px solid black;text-align:center;"
    //});
    ////et.hook()方法传入三个变量,第一个必填,是目标table,第二个必填,是目标的tr或者td,例:(0)表示第一个tr,(1,1)表示第二个tr的第二个td。第三个参数是回调函数,选填,如果不填,则hook直接返回获取到的dom对象,如果填入,则在callback中能使用该dom作为参数。
    //var firstTr = et.hook(et.table0, "(0)");
    //firstTr.style.fontSize = '30px';
    //et.hook(et.table0, "(2)", function (tr) {
    //    tr.style.color = "red";
    //    tr.style.fontWeight = "bold";
    //    tr.style.fontSize = "34px";
    //});
    //et.hook(et.table0, "(1,0)", function (td) {
    //    td.style.backgroundColor = "green";
    //});

    //32.et.addEvent()方法用于对指定的对象添加事件。通常与hook()方法配合使用。addEvent()方法需要传入三个参数,第一是dom对象,第二是事件类型,如click等(注意不要传入on字段),第三个参数是执行事件的内容,传入一个function。
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5],
    //    deuce: true,
    //    tableStyle:"text-align:center;font-size:30px;",
    //    tdStyle: "background-color:green;color:white;border:1px solid black;height:40px;"
    //});
    //et.hook(et.table0, "(0,0)", function (td) {
    //    et.addEvent(td, "click", function () {
    //        alert(td.id);
    //    });
    //});

    //33.et.clone()方法用于对指定的对象进行克隆,可以复制对象本身、对象的各种属性,以及对象重生等三种功能。实际上clone()是hook()方法的升级和封装。
    ////第一个参数和第二个参数同hook,第三个参数下面详述:
    //et.draw({
    //    targetId: "target",
    //    data: [1, 2, 3, 4, 5],
    //    deuce: true,
    //    tableStyle: "text-align:center;font-size:30px;",
    //    tdStyle: "background-color:green;color:white;border:1px solid black;height:40px;",
    //    style: "(0,0)[background-color:yellow;color:red]",
    //    attr: { "onclick": "(0,0)[alert(1)]" }
    //});
    //如果只传入两个参数,则返回指定对象的一个复制体,这里我们以tr为例,当然,也是可以复制td的。
    //var tr = et.clone(et.table0, "(0)");
    //et.table0.getElementsByTagName('tbody')[0].appendChild(tr);
    ////如果有传入第三个参数,并且第三个参数为字符串,则返回被指定对象的相关属性,这里以document.write()写在屏幕上给用户观看:
    //document.write("被克隆对象的是:table中的第一行tr的第一个td" + "<br>");
    //document.write("被克隆对象的id是:" + et.clone(et.table0, "(0,0)", "id") + "<br>");
    //document.write("被克隆对象的class是:" + et.clone(et.table0, "(0,0)", "class") + "<br>");
    //document.write("被克隆对象的innerHTML是:" + et.clone(et.table0, "(0,0)", "html") + "<br>");
    //document.write("被克隆对象的style是:" + et.clone(et.table0, "(0,0)", "style") + "<br>");
    //document.write("被克隆对象的style中的color是:" + et.clone(et.table0, "(0,0)", "style[color]") + "<br>");
    //document.write("被克隆对象的attr中的onclick是:" + et.clone(et.table0, "(0,0)", "attr[onclick]") + "<br>");

    //如果第三个参数为object,则是对克隆体进行设置:
    //et.clone(et.table0, "(1)", {
    //    id: "xiugai",//传入id、cls、style、html、attr等,如果是 非数组 则传给tr,如果是 数组 则传给td,当然,如果捕获的是td,则只能传入 非数组。
    //    cls: "newClass",
    //    style: ["background-color:red", "background-color:blue", "background-color:brown"],
    //    html: [11, 22, 33],
    //    attr: { "onclick": ["alert(1)", "", "alert(2)"] },
    //    parent: et.table0//这里是设置克隆体的将会append到哪一个父元素下。
    //});

    //34.上面已经介绍完了EasyTable的全部主要内容。在et中还存在一些内部使用的方法,它们也可以作为外部方法使用,下面将顺便介绍:
    //et.isArray(param);//判断参数是不是数组
    //et.isDOM(param);//判断参数是不是dom页面元素
    //et.isString(param);//判断参数是不是字符串
    //et.isNumber(param);//判断参数是不是数字
    //et.isObject(param);//判断参数是不是对象
    //et.isIE();//不需要传参,判断当前浏览器是不是ie浏览器。

    //35.删除数组中的某个参数:
    //et.deleteArray(array,index);
    //使用示例:var arr = [1,2,3]; arr = et.deleteArray(arr,0);  console.log(arr);  //将会得到[2,3];

    //36.前置插入和后置插入,作用是在元素的前面插入一个元素(同级),或在其后面插入一个元素(同级)
    //insertBefore() 和 insertAfter()
    //使用示例:
    //var tar = document.getElementById("target");
    //var before = document.createElement("div");
    //var after = document.createElement("div");
    //et.insertBefore(tar,before);
    //et.insertAfter(tar,after);

    //37.addRule()和deleteRule()方法,可以用于在指定styleSheet中进行rules条目的操作:
    //使用示例:
    //var style = document.createElement("style");
    //style.type = "text/css";
    //document.getElementsByTagName("head")[0].appendChild(style);
    ////最后一个变量表示插入的位置,因为我们的stylesheet表格是新建的,所以还为空,就只能插入在第0 index的位置上。
    //var sheet = document.styleSheets[document.styleSheets.length - 1];
    //et.addRule(sheet, "#target", "background-color:yellow;width:100%;height:50px;", 0);
    ////为了让用户看到效果,我在下面写了一个简单的计时器,1秒后执行deleteRule()方法,就可以清除掉指定的样式。
    //var timer = setTimeout(function () {
    //    et.deleteRule(sheet, 0);
    //    clearTimeout(timer);
    //},1000);

    //38.注意:在使用EasyTable时不要修改table、tablenum、tableRecycle、init、inited等属性,否则EasyTable将会运行错误。
</script>
</html>

下面是EasyTable2.0的源码,提供给大家研究和学习:

// EasyTable.js  纯js插件,创建时间:2015.02.13 当前版本:2015.04.27
//备注:该插件虽然不需要jquery驱动,但配合jquery使用会更加高效。

/* 2015.2.17
 * 由于ie浏览器中对tr.cells属性不兼容,所以新版本中的cells查询全部改为getElementsByTagName("td");
 */
/* 2015.4.23
 * 处理 bug:在EasyTr和EasyTd中增加这两个名字的class,现在可以批量删除新添加的内容了。
 * 处理 bug:将EasyTable.tablenum在draw方法中全部替换为table.index。
 *
 * 添加内容:添加了destroy方法,现在可以回收EasyTable.tablenum的序列号了,妈妈再也不用担心我的序列号爆掉了!
 *           回收的时候请使用EasyTable.destroy(你的table);
 *
 * 添加内容:添加了var et = EasyTable。现在在使用时可以用et简写代替EasyTable了。
 */
/* 2015.4.24
 * 添加内容:在draw主方法的里面修改了id、class和style等方法,并将tr和td的方法直接合并,根据索引是(x)还是(x,y)格式来判断是tr还是td。
 * 添加内容:在EasyTr和EasyTd中增加id、class 现在可以在添加Tr和Td的时候顺便生成id和class了,但是请慎用id功能。
 *
 * 添加内容:添加了hook方法,该方法可以捕获一个table中的某一个tr或某一个指定td。
 *           例子1:EasyTable.hook(table,"(0,2)",function(target){ target.id = "sheep"; });
 *           例子2:var firstTr = et.hook(table,0); firstTd.setAttribute("onclick","alert('我是钩子勾住的表格的第一行。')");
 *           例子3:$(et.hook(table,0)).css("background-color","green");  //配合jquery使用。
 *
 * 添加内容:添加了EasyTable.table+index对象属性自动生成,以后获取table只需要EasyTable.table+index了。
 *           使用示例:EasyTable.draw({targetId;"something",col:3,data:[1,2,3]});
 *                     EasyTable.table0.style.backgroundColor = "red";
 *                     //如果进行清除:
 *                     EasyTable.destroy(et.table0);
 *                     //下次重建table时,还是用index 0 进行访问:
 *                     EasyTable.draw({targetId;"somethingagain",col:3,data:[4,5,6]});
 *                     EasyTable.table0.style.backgroundColor = "blue";
 *
 * 修改内容:更新destroy方法,可以直接放入自定义的table,也可以放入一个或多个et.table+index,如果destroy()方法中的参数为空,就会清除掉所有EasyTable,慎用。
 * 修改内容:原本的draw方法中的trAttr是按顺序的,现在可以按照序列号进行检索了。
 * 修改内容:原本的draw方法中的tdAttr的序列号是从1开始的,现在改为从0开始,并且由原来的 列、行检索 改为:行、列检索。
 */
/* 2015.4.25
 * 修改内容:将colspan和rowspan改为和上面一样的行、列(index从0开始)的检索
 * 处理 bug:将draw和addTr中的style.cssText后面的 = 改为 += ,这样就可以避免样式被覆盖的问题。
 * 修改内容:将colStyle和rowStyle改为和style的样式一致了。
 * 修改内容:修改destroy方法,现在可以一次性传入多个table,一次性销毁并回收序列号。
 * 添加内容:添加clone方法,现在可以克隆任意的tr或者td了。实际上clone是destroy的延伸。
 * 添加内容:添加draw方法中的target属性,现在除了targetId之外可以将table直接生成于指定对象的下方了。
 * 修改内容:将插件中的主方法里面的全部EasyTable字样换成et。最后的var et = EasyTable 改成 var EasyTable = et;这样做的目的是在min版本中尽可能地减少文件字符量。
 *
/* 2015.4.27
 * 修改内容:将所有以outerHTML=""的形式清除dom元素的语句全部使用removeChild代替。原因是在ie浏览器中,table、tr和td元素的outerHTML是只读的,无法对其进行操作。
 * 添加内容:添加addEvent方法。
 * 处理bug :将addTr中直接插入的父对象由table改为tbody,这样就可以兼容ie浏览器了。
 * 处理bug :修复addTd中当type为vertical时跳过总格数就会出现异常的bug。
 * 修改内容:将draw() addTr() 和 clone()中的attr方法的格式进行统一化。
 * 添加内容:在addTr中添加callback(tr,tds),其中tr为tr元素,tds为td的元素数组集合。
 */
/*
 * 提    示:EasyTable中的addRule、deleteRule、isIE、insertBefore、insertAfter、isDOM、isObject、isString、isNumber、isArray、deleteArray方法都可以随时调用。
 * 注    意:在使用EasyTable时不要修改table、tablenum、tableRecycle、init、inited等属性,否则EasyTable将会运行错误。
 */

var et = {
    tableNum: 0,
    tableRecycle: [],
    sheet: null,
    addRule: function (sheet, s, n, position) {
        ("insertRule" in sheet) ? sheet.insertRule(s + "{" + n + "}", position) : sheet.addRule(s, n, position);
    },
    deleteRule: function (sheet, position) {
        ("deleteRule" in sheet) ? sheet.deleteRule(position) : sheet.removeRule(position);
    },
    aR: function (sheet, o) {
        var rulelength = document.all ? sheet.rules.length : sheet.cssRules.length;//兼容ie8、9
        for (var i in o) {
            et.addRule(sheet, i, o[i], rulelength || 0);
        }
    },
    inited: false,
    init: function () {
        var ds = document.styleSheets, style = document.createElement("style");
        style.type = "text/css";
        document.getElementsByTagName("head")[0].appendChild(style);
        if (ds.length) {
            ds[ds.length - 1].etMark = "et";
        }
        else {
            ds[0].etMark = "et";
        }
        var rule = document.all ? 'rules' : 'cssRules';
        for (var i = 0; i < ds.length; i++) {
            if (ds[i].etMark == "et") {
                et.sheet = ds[i]; break;
            }
        }
        et.aR(et.sheet, { ".EasyTable": "border-collapse:collapse;width:100%;" });
    },
    insertBefore: function (target, add) {
        target.parentNode.insertBefore(add, target);
    },
    insertAfter: function (target, add) {
        var parent = target.parentNode;
        if (parent.lastChild == target) {
            parent.appendChild(add);
        }
        else {
            parent.insertBefore(add, target.nextSibling);
        }
    },
    isIE: function () { return navigator && navigator.userAgent.match(/msie/i); },
    setTableInnerHTMLinIE: function (table, html) {
        var temp = table.ownerDocument.createElement('div');
        temp.innerHTML = '<table><tbody>' + html + '</tbody></table>';
        if (table.tBodies.length == 0) {
            var tbody = document.createElement('tbody');
            table.appendChild(tbody);
        }
        table.replaceChild(temp.firstChild.firstChild, table.tBodies[0]);
    },
    isDOM: function (o) {
        return (typeof HTMLElement === 'object') ? (o instanceof HTMLElement) : (o && (typeof o === "object") && (o.nodeType === 1) && (typeof o.nodeName === "string"))
    },
    isObject: function (o) { return (typeof o == 'object') && (o.constructor == Object); },
    isNumber: function (n) { return (typeof n == 'number') && (n.constructor == Number); },
    isString: function (s) { return (typeof s == 'string') && (s.constructor == String); },
    isArray: function (a) { return (typeof a == 'object') && (a.constructor == Array); },
    deleteArray: function (a, n) { return a.slice(0, n).concat(a.slice(n + 1, a.length)) },
    draw: function (o) {
        if (!et.inited) { et.init(); et.inited = true; }
        function createTableContent(table, data, col, row, num, colspan, rowspan, colStyle, rowStyle, vertical) {
            function create() {
                var tmp = [];
                for (var c = 0; c < col; c++) {
                    tmp.push('<td>*</td>');
                }
                return tmp;
            }
            row = (row && et.isNumber(row) && row > 1) ? row : 0;
            var len = Math.ceil(data.length / col);
            len = len > row ? len : row;
            var sumRows = new Array(len);
            var sumSpace = 0;//总格数
            function initSumRows() {
                for (var i = 0; i < sumRows.length; i++) {
                    sumRows[i] = [];
                    for (var j = 0; j < col; j++) {
                        sumRows[i].push('<td>*</td>');
                        sumSpace++;
                    }
                }
            }
            function dealColspan(colspan) {
                if (colspan && et.isObject(colspan)) {
                    for (var i in colspan) {
                        if (i.match(/^\(\d+\,\d+\)$/g)) {
                            var x = parseInt(i.match(/\d+/g)[0]);
                            var y = parseInt(i.match(/\d+/g)[1]);
                            if (sumRows[x] && sumRows[x][y] && et.isNumber(colspan[i])) {
                                sumRows[x][y] = sumRows[y][x].replace('>*', ' colspan="' + colspan[i] + '">*');
                                var loader = (colspan[i] > col ? col : colspan[i]) - 1;
                                for (var j = loader; j > 0; j--) {
                                    if (sumRows[x][y + j]) {
                                        sumRows[x] = et.deleteArray(sumRows[x], (y + j));
                                        sumSpace--;
                                    }
                                    else {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            function dealRowspan(rowspan) {
                if (rowspan && et.isObject(rowspan)) {
                    for (var i in rowspan) {
                        if (i.match(/^\(\d+\,\d+\)$/g)) {
                            var x = parseInt(i.match(/\d+/g)[0]);
                            var y = parseInt(i.match(/\d+/g)[1]);
                            if (sumRows[x][y] && et.isNumber(rowspan[i])) {
                                sumRows[x][y] = sumRows[x][y].replace('>*', ' rowspan="' + rowspan[i] + '">*');
                                var loader = rowspan[i];
                                //loader表示跨度,下面我们需要判断跨度和目标对象的y坐标之和是否大于总行数,如果大于的话,我们需要根据大于的具体情况对行数进行补偿
                                if ((x + loader) > sumRows.length) {
                                    var len = x + loader - sumRows.length;
                                    for (var k = 0; k < len ; k++) {
                                        sumRows.push(create());
                                    }
                                }
                                for (var j = 1; j < loader; j++) {
                                    if (sumRows[x + j][y]) {
                                        if (sumRows[x][y].match(/(colspan=\")\d+(\")/g)) {
                                            var span = parseInt(sumRows[x][y].match(/(colspan=\")\d+(\")/g)[0].match(/\d+/)[0]);
                                            span = span > col ? col : span;
                                            for (var k = span; k > 0; k--) {
                                                sumRows[x + j] = et.deleteArray(sumRows[x + j], sumRows[x + j].length - 1);
                                                sumSpace--;
                                            }
                                        }
                                        else {
                                            sumRows[x + j] = et.deleteArray(sumRows[x + j], y);
                                        }
                                    }
                                    else {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            function expand() {
                if (sumSpace < data.length) {
                    var addSpace = data.length - sumSpace;
                    var addLine = Math.ceil(addSpace / col);
                    for (var i = 0; i < addLine; i++) {
                        sumRows.push(create());
                    }
                    len = addLine;
                }
            }
            function style(s, index) { return s ? (s[index] ? ' style="' + s[index] + '"' : '') : ""; }
            function fill() {
                var TrIndex = 0;
                var str = '<tr id="EasyTr' + num + '_' + TrIndex + '" class="EasyTr' + num + '"' + style(rowStyle, 0) + '>';
                var index = 0; //data的index;
                for (var i = 0; i < sumRows.length; i++) {
                    TrIndex += 1;
                    for (var j = 0; j < sumRows[i].length; j++) {
                        sumRows[i][j] = sumRows[i][j].replace('>*', ' id="EasyTd' + num + '_' + (TrIndex - 1) + '_' + j + '" class="EasyTd' + num + ' EasyColumn' + j + '"' + style(colStyle, j) + '>' + (data[index] ? data[index] : ''));
                        str += sumRows[i][j];
                        index++;
                    }
                    if (i < sumRows.length - 1) {
                        str += '</tr><tr id="EasyTr' + num + '_' + TrIndex + '" class="EasyTr' + num + '"' + style(rowStyle, TrIndex) + '>';
                    }
                }
                str += '</tr>';
                if (et.isIE()) {
                    et.setTableInnerHTMLinIE(table, str);
                }
                else {
                    var tbody = document.createElement("tbody");
                    tbody.innerHTML = str;
                    table.appendChild(tbody);
                }
                table.lastEmpty = data.length % col ? table.rows[table.rows.length - 1].getElementsByTagName("td")[data.length % col] : null;
            }
            function verticalFill() {
                var index = 0;
                var TrIndex = 0;
                table.vertical = true;
                for (var i = 0; i < col; i++) {
                    for (var j = 0; j < sumRows.length; j++) {
                        if (sumRows[j][i]) {
                            if (sumRows[j][i].match(/(rowspan=\")\d+(\")/g)) {
                                sumRows[j][i] = sumRows[j][i].replace('>*', '>' + (data[index] ? data[index] : ''));
                                var s = parseInt(sumRows[j][i].match(/(rowspan=\")\d+(\")/g)[0].match(/\d+/g)[0]);
                                if (s > 1) {
                                    for (var k = 1; k < s ; k++) {
                                        j = j + 1;
                                        sumRows[j].splice(0, 0, "");
                                    }
                                }
                            }
                            else {
                                sumRows[j][i] = sumRows[j][i].replace('>*', '>' + (data[index] ? data[index] : ''));
                            }
                            index++;
                        }
                    }
                }
                var str = '<tr id="EasyTr' + num + '_' + TrIndex + '" class="EasyTr' + num + '"' + style(rowStyle, 0) + '>';
                for (var i = 0; i < sumRows.length; i++) {
                    TrIndex += 1;
                    for (var j = 0; j < sumRows[i].length; j++) {
                        if (sumRows[i][j] != "") {
                            str += sumRows[i][j].replace(sumRows[i][j].match(/>/g)[0], ' id="EasyTd' + (TrIndex - 1) + '_' + j + '" class="EasyTd' + num + ' EasyColumn' + j + '"' + style(colStyle, j) + '>');
                            index++;
                        }
                    }
                    if (i < sumRows.length - 1) {
                        str += '</tr><tr id="EasyTr' + num + '_' + TrIndex + '" class="EasyTr' + num + '"' + style(rowStyle, TrIndex) + '>';
                    }
                }
                str += '</tr>';

                if (et.isIE()) {
                    et.setTableInnerHTMLinIE(table, str);
                }
                else {
                    var tbody = document.createElement("tbody");
                    tbody.innerHTML = str;
                    table.appendChild(tbody);
                }
                function getLast() {
                    if (row) {
                        for (var i = 0; i < col; i++) {
                            for (var j = 0; j < table.rows.length; j++) {
                                if (table.rows[j].getElementsByTagName("td")[i].innerHTML == "") {
                                    table.verticalY = j;
                                    table.verticalX = i;
                                    return table.rows[j].getElementsByTagName("td")[i];
                                }
                            }
                        }
                    }
                    else {
                        var r = table.rows, l = r.length - 1, aimTop = r[l - 1], aim = r[l];
                        for (var i = l; i > 0; i--) {
                            if (aimTop.lastChild.innerHTML != "") {
                                table.verticalY = i;
                                table.verticalX = col;
                                return aim.lastChild;
                            }
                            else {
                                aim = aimTop;
                                aimTop = r[i - 1];
                            }
                        }
                    }
                }
                function getLastSimple() {
                    table.verticalY = 0;
                    table.verticalX = data.length;
                    return table.rows[0].getElementsByTagName("td")[data.length];
                }
                table.lastEmpty = data.length == sumSpace ? null : (table.rows.length == 1 ? getLastSimple() : getLast());
            }
            initSumRows();
            dealColspan(colspan);
            dealRowspan(rowspan);
            expand();
            if (vertical) {
                verticalFill();
            }
            else {
                fill();
            }
        }
        if (et.isObject(o) && (et.isString(o.targetId) || et.isDOM(o.target))) { //主运算区
            var target = document.getElementById(o.targetId);
            var table = document.createElement("table");
            table.className = "EasyTable";
            function dealRecycle(num) {
                if (et.tableRecycle.length) {
                    if (et.tableRecycle.length == 1) {
                        var tmp = et.tableRecycle[0];
                        et.tableRecycle = [];
                        return tmp;
                    }
                    else {
                        var tmpArr = [], tmp = et.tableRecycle[0];
                        for (var i = 1; i < et.tableRecycle.length; i++) {
                            tmpArr.push(et.tableRecycle[i]);
                        }
                        et.tableRecycle = tmpArr;
                        return tmp;
                    }
                }
                else {
                    return num;
                }
            }
            table.index = dealRecycle(et.tableNum);
            table.id = "EasyTable" + table.index;
            var column = o.col || 3;
            function createEmptyDataGroup(column) {
                var tmp = [];
                for (var i = 0; i < column; i++) {
                    tmp.push("");
                }
                table.imempty = 1;
                return tmp;
            }
            var data = et.isArray(o.data) ? o.data : createEmptyDataGroup(column);
            var row = o.row || null; //行数为可选项,当需要应用到跨行和跨列的处理而出现问题时可以用该参数对其进行修正
            function dealCRstyle(style) {//CR表示col和row
                if (style) {
                    var tmp = [];
                    if (!et.isArray(style)) {
                        style = [style];
                    }
                    for (var i = 0; i < style.length; i++) {
                        if (style[i].match(/^\(\d+\)\[[\s\S]*\]$/g)) {
                            tmp[parseInt(style[i].match(/\(\d+\)/g)[0].slice(1, -1))] = style[i].match(/\[[\s\S]*\]/g)[0].slice(1, -1);
                        }
                    }
                    return tmp;
                }
                return null;
            }
            var colStyle = dealCRstyle(o.colStyle), rowStyle = dealCRstyle(o.rowStyle);
            var colspan = o.colspan || null, rowspan = o.rowspan || null;
            var vertical = o.type == "vertical" ? true : false;
            if (o.tableStyle) { eval('et.aR(et.sheet,{"#EasyTable' + table.index + '":"' + o.tableStyle + '"})'); }
            if (o.trStyle) { eval('et.aR(et.sheet,{".EasyTr' + table.index + '":"' + o.trStyle + '"})'); }
            if (o.tdStyle) { eval('et.aR(et.sheet,{".EasyTd' + table.index + '":"' + o.tdStyle + '"})'); }
            if (o.deuce) {//该属性用于决定是否平分全部列宽
                eval('et.aR(et.sheet,{".EasyTd' + table.index + '":"width:' + parseInt(100 / column) + '%"})');
                var rulelength = document.all ? et.sheet.rules.length : et.sheet.cssRules.length;//兼容ie8、9的et.sheet.rules.length
                table.deuce = rulelength - 1;
            }
            createTableContent(table, data, column, row, table.index, colspan, rowspan, colStyle, rowStyle, vertical);
            table.col = o.col || 3;
            var parent = document.getElementById(o.targetId) || o.target;
            parent.appendChild(table);
            function deuce() {
                if (o.deuce) {
                    et.deleteRule(et.sheet, table.deuce);
                    eval('et.aR(et.sheet,{".EasyTd' + table.index + '":"width:' + parseInt(100 / table.col) + '%"})');
                    var rulelength = document.all ? et.sheet.rules.length : et.sheet.cssRules.length;
                    table.deuce = rulelength - 1;
                }
            }
            function addCol(type, col) {
                var plus = 0, index = 0;
                for (var i in col) {
                    for (var j = 0; j < table.rows.length; j++) {
                        var aim = document.getElementById("EasyTd" + table.index + "_" + j + "_" + i);
                        if (aim && et.isNumber(col[i]) && col[i] > 0) {
                            for (var k = 0; k < col[i]; k++) {
                                var newChild = document.createElement("td");
                                newChild.id = type + "Col" + table.index + "_" + (index++);
                                newChild.className = aim.className + " " + type + "Col " + type + "Col" + table.index + "_" + i;
                                if (type == "prepend") {
                                    et.insertBefore(aim, newChild);
                                }
                                else {
                                    et.insertAfter(aim, newChild);
                                }
                            }
                        }
                    }
                    plus += et.isNumber(col[i]) ? col[i] : 0;
                }
                table.col += plus;
                deuce();
            }
            function addRow(type, row) {
                for (var i in row) {
                    var aim = document.getElementById("EasyTr" + table.index + "_" + i);
                    if (aim && et.isNumber(row[i]) && row[i] > 0) {
                        for (var j = row[i]; j > 0; j--) {
                            var newChild = document.createElement("tr");
                            newChild.className = type + "Row" + table.index + "_" + i + " EasyTr" + table.index;
                            for (var k = 0; k < table.col; k++) {
                                newChild.innerHTML += '<td id="' + type + 'RowTd' + i + '_' + j + '_' + k + '" class="EasyTd' + table.index + ' ' + type + 'Row ' + type + 'Row' + table.index + '_' + i + '"></td>';
                            }
                            if (type == "prepend") {
                                et.insertBefore(aim, newChild);
                            }
                            else {
                                et.insertAfter(aim, newChild);
                            }
                        }
                    }
                }
            }
            function eCR(val, type) {//empty col or row
                if (et.isNumber(val)) { val = [val]; }
                var childs = table.rows, c = type == "col" ? table.col : table.rows.length;
                for (var i = 0; i < val.length; i++) {
                    var v = val[i] < c ? val[i] : null;
                    if (v != null) {
                        if (type == "col") {
                            for (var j = 0; j < childs.length; j++) {
                                childs[j].getElementsByTagName("td")[v].innerHTML = "";
                            }
                        }
                        else {
                            for (var j = 0; j < childs[v].getElementsByTagName("td").length; j++) {
                                childs[v].getElementsByTagName("td")[j].innerHTML = "";
                            }
                        }
                    }
                }
            }
            function rCR(val, type) {//remove col or row
                if (et.isNumber(val)) { val = [val]; }
                var childs = table.rows, c = type == "col" ? table.col : table.rows.length;
                val = val.sort().reverse();
                for (var i = 0; i < val.length; i++) {
                    var v = val[i] < c ? val[i] : null;
                    if (v != null) {
                        if (type == "col") {
                            for (var j = 0; j < childs.length; j++) {
                                childs[j].removeChild(childs[j].getElementsByTagName("td")[v]);
                            }
                            table.col--;
                        }
                        else {
                            childs[v].parentNode.removeChild(childs[v]);
                        }
                    }
                }
                deuce();
            }
            if (o.prependCol && et.isObject(o.prependCol)) {
                addCol("prepend", o.prependCol);
            }
            if (o.appendCol && et.isObject(o.appendCol)) {
                addCol("append", o.appendCol);
            }
            if (o.prependRow && et.isObject(o.prependRow)) {
                addRow("prepend", o.prependRow);
            }
            if (o.appendRow && et.isObject(o.appendRow)) {
                addRow("append", o.appendRow);
            }
            if (et.isNumber(o.emptyCol) || et.isArray(o.emptyCol)) {
                eCR(o.emptyCol, "col");
            }
            if (et.isNumber(o.emptyRow) || et.isArray(o.emptyRow)) {
                eCR(o.emptyRow, "row");
            }
            if (et.isNumber(o.removeCol) || et.isArray(o.removeCol)) {
                rCR(o.removeCol, "col");
            }
            if (et.isNumber(o.removeRow) || et.isArray(o.removeRow)) {
                rCR(o.removeRow, "row");
            }
            function RS(n, c) { //去除头尾空格或者指定符号
                var c = c || " ";
                while (n.slice(0, 1) == c) { n = n.slice(1); } while (n.slice(-1) == c) { n = n.slice(0, -1); } return n;
            }
            function ICSH(kind, a) {//id,class,style,html
                var s1 = (kind == "id" ? "id=" : (kind == "class" ? "className+=" : (kind == "style" ? "style.cssText+=" : "innerHTML=")));
                var s2 = kind == "class" ? '" ' : '"';
                if (!et.isArray(a)) {
                    a = [a];
                }
                for (var i = 0; i < a.length; i++) {
                    if (a[i]) {
                        var aim, index, x, y, content;
                        if (a[i].match(/^\(\d+\)\[[\s\S]*\]$/g)) {
                            index = parseInt(a[i].match(/\(\d+\)/g)[0].slice(1, -1));
                            aim = table.rows[index];
                            content = RS(a[i].match(/\[[\s\S]*\]/g)[0].slice(1, -1));
                        }
                        else if (a[i].match(/^\(\d+\,\d+\)\[[\s\S]*\]$/g)) {
                            index = a[i].match(/\(\d+\,\d+\)/g)[0].slice(1, -1).split(",");
                            x = parseInt(index[0]);
                            y = parseInt(index[1]);
                            if (table.rows[x]) {
                                aim = table.rows[x].getElementsByTagName("td")[y];
                                content = RS(a[i].match(/\[[\s\S]*\]/g)[0].slice(1, -1));
                            }
                        }
                        if (aim) {
                            eval('aim.' + s1 + s2 + content + '"');
                        }
                    }
                }
            }
            function Attr(o) {
                var tr = table.rows;
                for (var i in o) {
                    if (!et.isArray(o[i])) {
                        o[i] = [o[i]];
                    }
                    for (var j = 0; j < o[i].length; j++) {
                        if (o[i][j] && (o[i][j].match(/^\(\d+\)\[[\s\S]*\]$/g) || o[i][j].match(/^\(\d+\,\d+\)\[[\s\S]*\]$/g))) {
                            var aim, index, x, y, attr;
                            attr = o[i][j].match(/\[[\s\S]*\]/g)[0].slice(1, -1);
                            if (o[i][j].match(/^\(\d+\)\[[\s\S]*\]$/g)) {
                                index = parseInt(o[i][j].match(/\(\d+\)/g)[0].slice(1, -1));
                                aim = tr[index];
                            }
                            else {
                                index = o[i][j].match(/\(\d+\,\d+\)/g)[0].slice(1, -1).split(",");
                                x = parseInt(index[0]);
                                y = parseInt(index[1]);
                                aim = tr[x].getElementsByTagName("td")[y];
                            }
                            if (aim) {
                                aim.setAttribute(i, attr);
                            }
                        }
                    }
                }
            }
            if (o.id) {
                ICSH("id", o.id);
            }
            if (o.cls) {
                ICSH("class", o.cls);
            }
            if (o.style) {
                ICSH("style", o.style);
            }
            if (o.html) {
                ICSH("html", o.html);
            }
            if (o.attr && et.isObject(o.attr)) {
                Attr(o.attr);
            }
            if (!et.tableRecycle.length) {
                et.tableNum++;
            }
            table.row = table.rows.length;
            if (o.callback) {
                o.callback(table, table.id);
            }
            et['table' + table.index] = table;
        }
    },
    addTr: function (o) {
        if (et.isDOM(o.target) && o.target.col != undefined && o.target.row != undefined) {
            var table = o.target;
            table.row++;
            function createEmptyDataGroup(column, data) {
                var tmp = [];
                tmp.push(data ? data : "");
                for (var i = 1; i < column; i++) {
                    tmp.push("");
                }
                return tmp;
            }
            function deal(d) {
                if (d.length < table.col) {
                    for (var i = 0; i <= table.col - d.length; i++) {
                        d.push("");
                    }
                }
                return d;
            }
            var data = et.isArray(o.data) ? deal(o.data) : createEmptyDataGroup(table.col, o.data);
            var tr, tds = [];
            if (table.imempty) {
                for (var i = 0; i < table.rows[0].getElementsByTagName("td").length; i++) {
                    table.rows[0].getElementsByTagName("td")[i].innerHTML = data[i];
                    tds.push(table.rows[0].getElementsByTagName("td")[i]);
                }
                table.imempty = 0;
                tr = table.rows[0];
            }
            else {
                tr = document.createElement("tr");
                tr.className = "EasyTr" + table.index + " EasyTr";
                tr.id = "EasyTr" + table.index + "_" + table.rows.length;
                for (var i = 0; i < table.col; i++) {
                    var td = document.createElement("td");
                    td.id = "EasyTd" + table.rows.length + "_" + i;
                    td.className = "EasyTd" + table.index + " EasyColumn" + i;
                    td.innerHTML = data[i];
                    tds.push(td);
                    tr.appendChild(td);
                }
                var parent = table.getElementsByTagName("tbody") ? table.getElementsByTagName("tbody")[0] : table;
                parent.appendChild(tr);
            }
            function IdOrClassOrStyle(kind, o) {
                var s1 = (kind == "id" ? "id=" : (kind == "class" ? "className+=" : "style.cssText+="));
                var s2 = kind == "class" ? '" ' : '"';
                if (et.isArray(o)) {
                    for (var i = 0; i < tds.length; i++) {
                        if (o[i]) {
                            eval('tds[i].' + s1 + s2 + o[i] + '"');
                        }
                    }
                }
                else {
                    eval('tr.' + s1 + s2 + o + '"');
                }
            }
            if (o.id) {//不建议使用id方法,因为会覆盖掉原来的id,可能会影响自带的一些属性。
                IdOrClassOrStyle("id", o.id);
            }
            if (o.cls) {
                IdOrClassOrStyle("class", o.cls);
            }
            if (o.style) {
                IdOrClassOrStyle("style", o.style);
            }
            if (o.attr) {
                if (et.isObject(o.attr)) {
                    for (var i in o.attr) {
                        if (et.isArray(o.attr[i])) {
                            for (var j = 0; j < o.attr[i].length; j++) {
                                if (tds[j] && o.attr[i][j]) {
                                    tds[j].setAttribute(i, o.attr[i][j]);
                                }
                            }
                        }
                        else if (o.attr[i]) {
                            tr.setAttribute(i, o.attr[i]);
                        }
                    }
                }
            }
            if (o.toggleStyle) {
                if (table.trToggleStyle == undefined) {
                    table.trToggleStyle = true;
                }
                if (table.trToggleStyle) {
                    table.trToggleStyle = false;
                    tr.style.cssText += o.toggleStyle;
                }
                else {
                    table.trToggleStyle = true;
                }
            }
            if (o.toggleAttr) {
                if (table.trToggleAttr == undefined) {
                    table.trToggleAttr = true;
                }
                if (table.trToggleAttr) {
                    table.trToggleAttr = false;
                    if (et.isObject(o.toggleAttr)) {
                        for (var i in o.toggleAttr) {
                            tr.setAttribute(i, o.toggleAttr[i]);
                        }
                    }
                }
                else {
                    table.trToggleAttr = true;
                }
            }
            if (o.callback) {
                o.callback(tr, tds);
            }
        }
    },
    addTd: function (o) {
        if (et.isDOM(o.target) && o.target.col != undefined && o.target.row != undefined) {
            var table = o.target, aimTd;
            function getNextSibling(startBrother) {
                endBrother = startBrother.nextSibling;
                if (!endBrother) { return null; }
                while (endBrother.nodeType != 1) {
                    endBrother = endBrother.nextSibling;
                }
                return endBrother;
            }
            if (table.lastEmpty) {
                aimTd = table.lastEmpty;
                if (table.vertical) {
                    if (table.rows[table.verticalY + 1] && table.rows[table.verticalY + 1].getElementsByTagName("td")[table.verticalX]) {
                        table.lastEmpty = table.rows[table.verticalY + 1].getElementsByTagName("td")[table.verticalX];
                        table.verticalY += 1;
                    }
                    else if (table.rows[0].getElementsByTagName("td")[table.verticalX + 1]) {
                        table.lastEmpty = table.rows[0].getElementsByTagName("td")[table.verticalX + 1];
                        table.verticalX += 1;
                        table.verticalY = 0;
                    }
                    else {
                        table.lastEmpty = null;
                        table.vertical = null;
                    }
                }
                else {
                    table.lastEmpty = getNextSibling(table.lastEmpty);
                }
            }
            else {
                table.vertical = null;
                var tr;
                if (table.imempty) {
                    tr = table.rows[0];
                    table.imempty = 0;
                }
                tr = document.createElement("tr");
                tr.className = "EasyTr" + table.index;
                tr.id = "EasyTr" + table.index + "_" + table.rows.length;
                table.row++;
                for (var i = 0; i < table.col; i++) {
                    var td = document.createElement("td");
                    td.id = "EasyTd" + table.rows.length + "_" + i;
                    td.className = "EasyTd" + table.index + " EasyColumn" + i + " EasyTd";
                    tr.appendChild(td);
                }
                aimTd = tr.getElementsByTagName("td")[0];
                table.lastEmpty = tr.getElementsByTagName("td")[1];//如果没有那就是undefined,那么下次又会再创建一行新的tr
                et.insertAfter(table.rows[table.rows.length - 1], tr);
            }
            if (o.data || o.data == 0) {
                aimTd.innerHTML = o.data;
            }
            if (o.style) {
                aimTd.style.cssText = o.style;
            }
            if (o.id) {//一般不建议使用该方法,可能会干扰EasyTable的一些属性。
                aimTd.id = o.id;
            }
            if (o.cls) {
                aimTd.className += " " + o.cls;
            }
            if (et.isObject(o.attr)) {
                for (var i in o.attr) {
                    aimTd.setAttribute(i, o.attr[i]);
                }
            }
            if (o.toggleStyle) {
                if (table.tdToggleStyle == undefined) {
                    table.tdToggleStyle = true;
                }
                if (table.tdToggleStyle) {
                    table.tdToggleStyle = false;
                    aimTd.style.cssText += o.toggleStyle;
                }
                else {
                    table.tdToggleStyle = true;
                }
            }
            if (o.toggleAttr) {
                if (table.tdToggleAttr == undefined) {
                    table.tdToggleAttr = true;
                }
                if (table.tdToggleAttr) {
                    table.tdToggleAttr = false;
                    if (et.isObject(o.toggleAttr)) {
                        for (var i in o.toggleAttr) {
                            aimTd.setAttribute(i, o.toggleAttr[i]);
                        }
                    }
                }
                else {
                    table.tdToggleAttr = true;
                }
            }
            if (o.callback) {
                o.callback(aimTd);
            }
        }
    },
    destroy: function () {
        var arg = arguments;
        if (arg.length) {
            for (var i = 0; i < arg.length; i++) {
                if (et.isDOM(arg[i])) {
                    if (et.isNumber(arg[i].index) && et['table' + arg[i].index]) {
                        //et['table' + arg[i].index] = undefined;
                        delete et['table' + arg[i].index];
                        et.tableRecycle.push(arg[i].index);
                    }
                    arg[i].parentNode.removeChild(arg[i]);
                }
            }
        }
        else {
            for (var i = 0; i < et.tableNum; i++) {
                if (et['table' + i]) {
                    et['table' + i].parentNode.removeChild(et['table' + i]);
                    //et['table' + i] = undefined;
                    delete et['table' + i];
                }
            }
            et.tableNum = 0;
            et.tableRecycle = [];
        }
    },
    hook: function (table, aim, callback) {
        if (et.isDOM(table) && table.col != undefined && table.row != undefined) {
            var target;
            if (et.isNumber(aim)) {
                target = table.rows[aim];
            }
            else if (et.isString(aim)) {
                if (aim.match(/^\(?\d+\)?$/g)) {
                    target = table.rows[parseInt(aim.match(/\d+/g)[0])];
                }
                else if (aim.match(/^\(?\d+\,\d+\)?$/g)) {
                    var i = aim.match(/\d+\,\d+/g)[0].split(",");
                    var x = parseInt(i[0]), y = parseInt(i[1]);
                    target = table.rows[x].getElementsByTagName("td")[y];
                }
            }
            if (target) {
                if (callback) {
                    callback(target);
                }
                return target;
            }
        }
    },
    clone: function (table, aim, type) {
        var target = et.hook(table, aim), o = type;
        if (target) {
            if (!target.cloned) { target.cloned = 1; }
            var c = target.cloneNode(true), rd = c.tagName.toLowerCase();//rd => tr or td
            c.id = target.id + "_clone" + target.cloned; target.cloned++;
            function ICSH(kind, o) {
                var s1 = (kind == "id" ? "id=" : (kind == "class" ? "className+=" : (kind == "style" ? "style.cssText+=" : "innerHTML=")));
                var s2 = kind == "class" ? '" ' : '"';
                if (et.isArray(o) && rd == "tr") {
                    var cTd = c.getElementsByTagName("td");
                    if (cTd.length) {
                        for (var i = 0; i < cTd.length; i++) {
                            if (o[i] && cTd[i]) {
                                eval('cTd[i].' + s1 + s2 + o[i] + '"');
                            }
                        }
                    }
                }
                else {
                    eval('c.' + s1 + s2 + o + '"');
                }
            }
            function Attr(o) {
                if (et.isObject(o)) {
                    for (var i in o) {
                        if (et.isArray(o[i]) && c.tagName.toLowerCase() == "tr") {
                            var cTd = c.getElementsByTagName("td");
                            for (var j = 0; j < o[i].length; j++) {
                                if (cTd[j] && o[i][j]) {
                                    cTd[j].setAttribute(i, o[i][j]);
                                }
                            }
                        }
                        else {
                            c.setAttribute(i, o[i]);
                        }
                    }
                }
            }
            if (et.isObject(o)) {
                if (o.id) { ICSH("id", o.id); }
                if (o.cls) { ICSH("class", o.cls); }
                if (o.style) { ICSH("style", o.style); }
                if (o.html) { ICSH("html", o.html); }
                if (o.attr) { Attr(o.attr); }
                if (o.parent) {
                    if (et.isDOM(o.parent)) {
                        if (o.parent.tagName.toLowerCase() == "table" && o.parent.getElementsByTagName("tbody")) {
                            o.parent.getElementsByTagName("tbody")[0].appendChild(c);
                        }
                        else {
                            o.parent.appendChild(c);
                        }
                    }
                }
                return c;
            }
            else if (et.isString(o)) {
                function d(n) { //将形如background-color的字符变成backgroundColor
                    if (n.indexOf("-") > 0) {
                        var t = n.split("-"), tmp = t[0];
                        for (var i = 1; i < t.length; i++) {
                            tmp += t[i].slice(0, 1).toUpperCase() + t[i].slice(1);
                        }
                        return tmp;
                    }
                    return n;
                }
                if (o == "html") { return c.innerHTML; }
                else if (o == "id") { return target.id; }
                else if (o == "class") { return c.className; }
                else if (o == "style") { return c.style.cssText; }
                else if (o.match(/^style\[[\s\S]*\]$/g)) {
                    var s = d(o.match(/\[[\s\S]*\]/g)[0].slice(1, -1));
                    if (eval('c.style.' + s)) { return eval('c.style.' + s); }
                }
                else if (o.match(/^attr\[[\s\S]*\]$/g)) {
                    var s = o.match(/\[[\s\S]*\]/g)[0].slice(1, -1);
                    if (c.getAttribute(s)) { return c.getAttribute(s); }
                }
            }
            else {
                return c;
            }
        }
    },
    addEvent: function (obj, event, handler) {
        if (window.attachEvent) {
            obj.attachEvent("on" + event, handler);
        } else if (window.addEventListener) {
            obj.addEventListener(event, handler, false);
        }
    }
}
var EasyTable = et;

最后是给出下载链接,已经打包好的了,包括demo.html,EasyTable.js和EasyTable.min.js。

http://download.csdn.net/detail/sinolzeng/8637245

时间: 2024-10-14 05:54:53

EasyTable2.0 功能更加强大,bug全面修复的html table插件!的相关文章

软件工程腾讯QQ (1)优点:聊天功能比较强大。同时提供安全登陆通道,保障了用户信息的安全性。应用的人群范围比较广 缺点:要展示的信息量太多,用户个人信息容易泄露。有一些弄虚作假通过其欺骗用户上当。 (2)有使用需要自己下载 (3)版本更新修复bug,定期更新版本

1.软件工程未来的发展方向是什么? 2.编程基础不好,我能学习好软件工程吗? 3.软件工程跟物联网之间的区别与联系是什么? 4.软件工程在现实生活中有哪些应用? 5.在软件工程的分类中,如何选择一个适合自己的? 6.软件工程的学习中最难克服的阶段是什么? 7.怎样学好软件工程? 腾讯QQ (1)优点:聊天功能比较强大.同时提供安全登陆通道,保障了用户信息的安全性.应用的人群范围比较广 缺点:要展示的信息量太多,用户个人信息容易泄露.有一些弄虚作假通过其欺骗用户上当. (2)有使用需要自己下载 (

Android 5.0原生bug及修复方法

Android 5.0已经来了,这个版本改动非常大,也意味着会有更多的bug隐藏在其中,我会在这篇文章中一直更新自己遇到的原生bug及修复方法. 1.bug1 现象:5.0中ActivityManagerService.keyguardWaitingForActivityDrawn ()接口替换了4.4中ActivityManagerService.dismissKeyguardOnNextActivity()接口,但是带来了一个显示bug,现象是keyguard隐藏后activity窗口还没显

HIVE 0.11版本的bug

HIVE 0.11版本的bug 两次{{group by}}的bug  https://issues.apache.org/jira/browse/HIVE-5149 SELECT key, COUNT(*) FROM ( SELECT key, value, COUNT( * ) FROM src GROUP BY key, value ) a GROUP BY key; 特点是两次 group by ,外层字段少于内层,2次集合函数.可以把中间的查询做成临时表回避这个bug HIVE 0.1

pandas的筛选功能,跟excel的筛选功能类似,但是功能更强大。

Select rows from a DataFrame based on values in a column -pandas 筛选 https://stackoverflow.com/questions/17071871/select-rows-from-a-dataframe-based-on-values-in-a-column-in-pandas pandas的筛选功能,跟excel的筛选功能类似,但是功能更强大. 在SQL数据中, 我们可以用这样的语句: select * from

一个功能更强大的函数,也是用正则表达式写的

<% Option Explicit Function stripHTML(strtext) dim arysplit,i,j, strOutput arysplit=split(strtext,"<") if len(arysplit(0))>0 then j=1 else j=0 for i=j to ubound(arysplit) if instr(arysplit(i),">") then arysplit(i)=mid(arysp

Rust这种新型的语言注定火不起来,功能太强大(特性太多),还不如用成熟稳定强大的C/C++,而且生态不行、所以恶性循环

这种新型的语言注定火不起来,功能太强大(特性太多),还不如用成熟稳定强大的C/C++,,而Golang足够简单,入门快,编译快,性能也强悍,解决了服务端开发人员的痛点,,注定被大多数人接受... golang 针对的方向和他不同,虽然是同一时期的,但我觉得不太适合用来比较 拿 Go 来类比,不是比功能定位,而是比被接受的容易度,其他方面都很OK 且 容易上手的语言后来者居上的可能性非常大,,,如果从功能上对比的话,Go 主要定位解决分布式系统,服务器应用开发,主要竞争对手是 Java.Pytho

转载:ios程序编译链接参数 all_load 的 ld duplicate symbol _main 的 bug及修复

转载自:http://www.cnblogs.com/dabaopku/archive/2012/12/12/2813940.html ios程序编译链接参数 all_load 的 ld duplicate symbol _main 的 bug及修复 问题 -all_load 是在Objective-C 编译时常用到的一个参数,比如这篇文章所介绍的,生成静态库的一些问题-all_load.但是我们在加入这个参数后,有时会出现"ld: duplicate symbol _main"的错误

Android下载管理DownloadManager功能扩展和bug修改

http://www.trinea.cn/android/android-downloadmanager-pro/ 本文主要介绍如何修改Android系统下载管理,以支持更多的功能及部分bug修改和如何编译生效.目前内容包括暂停下载.继续下载.通知设置NotiExtra和NotiClass.wifi切换到3g自动暂停.Bug修改. PS: 很多童鞋不是自己做rom,所以就算修改了系统源码编译出来的包在其他系统上也不通用这里推荐[email protected](并不是我的开源项目,我的项目为[e

功能更强大的格式化工具类 FormatUtils.java

package com.util; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 功能更强大的格式化工具类 */ public class FormatUtils { private static SimpleDateFormat second = new SimpleDateForma