zoukankan      html  css  js  c++  java
  • 【Javascript】Javascript横向/纵向合并单元格TD

    > 需求是这样滴(>_<)

    在报表系统中,涉及“HTML的TD单元格的合并”恐怕为数不少。

    比如,从DB查得数据并经过后台的整理后,可能是这样的:

    Table1

       JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
    1 ANALYST 6000 1 7788 SCOTT ANALYST 7566 4/19/1987 3000.00   20
    1 ANALYST 6000 2 7902 FORD ANALYST 7566 12/3/1981 3000.00   20
    2 CLERK 4150 3 7934 MILLER CLERK 7782 1/23/1982 1300.00   10
    2 CLERK 4150 4 7900 JAMES CLERK 7698 12/3/1981 950.00   30
    2 CLERK 4150 5 7369 SMITH CLERK 7902 12/17/1980 800.00   20
    2 CLERK 4150 6 7876 ADAMS CLERK 7788 5/23/1987 1100.00   20
    3 MANAGER 8275 7 7698 BLAKE MANAGER 7839 5/1/1981 2850.00   30
    3 MANAGER 8275 8 7566 JONES MANAGER 7839 4/2/1981 2975.00   20
    3 MANAGER 8275 9 7782 CLARK MANAGER 7839 6/9/1981 2450.00   10
    4 PRESIDENT 5000 10 7839 KING PRESIDENT   11/17/1981 5000.00   10
    5 SALESMAN 5600 11 7844 TURNER SALESMAN 7698 9/8/1981 1500.00 0.00 30
    5 SALESMAN 5600 12 7654 MARTIN SALESMAN 7698 9/28/1981 1250.00 1400.00 30
    5 SALESMAN 5600 13 7521 WARD SALESMAN 7698 2/22/1981 1250.00 500.00 30
    5 SALESMAN 5600 14 7499 ALLEN SALESMAN 7698 2/20/1981 1600.00 300.00 30

     

    为了让用户更清晰地查看报表,结果可能需要是这样的(各职位的薪水总额及分布明细):

    Table2

       JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
    1 ANALYST 6000 1 7788 SCOTT ANALYST 7566 4/19/1987 3000.00   20
    2 7902 FORD ANALYST 7566 12/3/1981 3000.00   20
    2 CLERK 4150 3 7934 MILLER CLERK 7782 1/23/1982 1300.00   10
    4 7900 JAMES CLERK 7698 12/3/1981 950.00   30
    5 7369 SMITH CLERK 7902 12/17/1980 800.00   20
    6 7876 ADAMS CLERK 7788 5/23/1987 1100.00   20
    3 MANAGER 8275 7 7698 BLAKE MANAGER 7839 5/1/1981 2850.00   30
    8 7566 JONES MANAGER 7839 4/2/1981 2975.00   20
    9 7782 CLARK MANAGER 7839 6/9/1981 2450.00   10
    4 PRESIDENT 5000 10 7839 KING PRESIDENT   11/17/1981 5000.00   10
    5 SALESMAN 5600 11 7844 TURNER SALESMAN 7698 9/8/1981 1500.00 0.00 30
    12 7654 MARTIN SALESMAN 7698 9/28/1981 1250.00 1400.00 30
    13 7521 WARD SALESMAN 7698 2/22/1981 1250.00 500.00 30
    14 7499 ALLEN SALESMAN 7698 2/20/1981 1600.00 300.00 30

     这就需要我们对单元格进行相应的合并。

    一般来说,有两种处理方法,

    1. 在编写HTML时已设置单元格的合并;
    2. 在编写HTML时未作合并处理,后期由Javascript完成单元格合并工作。

    本文讲的是第2种情况。

    合并单元格的步骤

    比如,我要把上表Table1中数值为ANALYST的两个单元格合并。

    JOB
    ANALYST
    ANALYST
    • 我们首先需要将第二个ANALYST的单元格删除掉
    • 然后设置第一个ANALYST的单元格的rowSpan属性为2(表示“跨越2行”)

    > 写得不好的公用方法

    之前写了一个公用Javascript方法,用以合并相邻间文本相同的单元格。

    这个方法写得不好,有明显的Bug。对已做过合并的Table,这个方法有可能导致合并单元格错误。

    主要的原因在于,对于合并过单元格的表格,那么被合并的行就会相应的少一个TD,而此方法依旧按未合并过单元格的情况来获取TD对象。

    比如,获取第二列的所有单元格,此程序用“获取全部TR中的第二个TD”来实现,这在未合并过单元格的Table是正确的,但对于合并过单元格的Table,则未必,因为被合并的行相应地少一个单元格。

    此处将代码贴出,希望大家引以为鉴

    function mergeCell(tableObj, col) {
            var $tab = $(tableObj);
            var $trs = $tab.find("tr");
            
            var oldval;
            var firstTD;
            var counter = 0;
            $trs.each(function(index) {
                
                if (!oldval && !firstTD) {
                    oldval = $(this).find("td:eq(" + col + ")").text();
                    firstTD = $(this).find("td:eq(" + col + ")").get(0);
                    counter = 0;
                    counter++;
                } else {
                    if ($(this).find("td:eq(" + col + ")").text() == oldval) {
                        $(this).find("td:eq(" + col + ")").remove();
                        counter++;
                    } else {
                        $(firstTD).attr("rowSpan", counter);
                        oldval = $(this).find("td:eq(" + col + ")").text();
                        firstTD = $(this).find("td:eq(" + col + ")").get(0);
                        counter = 0;
                        counter++;
                    }
                }
                
                if (index >= $trs.length - 1) {
                    $(firstTD).attr("rowSpan", counter);
                }
                
            });
        }
    mergeCell

     页面DEMO如下(HTML代码,较长):

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    
    <script type="text/javascript" src="../js/jquery.js"></script>
    <script type="text/javascript" src="../js/tdmerger.js"></script>
    <script type="text/javascript">
        $().ready(function() {
    
            mergeCell($("#list_table").get(0), 1);
            mergeCell($("#list_table").get(0), 2);
            
        });
        
        function mergeCell(tableObj, col) {
            var $tab = $(tableObj);
            var $trs = $tab.find("tr");
            
            var oldval;
            var firstTD;
            var counter = 0;
            $trs.each(function(index) {
                
                if (!oldval && !firstTD) {
                    oldval = $(this).find("td:eq(" + col + ")").text();
                    firstTD = $(this).find("td:eq(" + col + ")").get(0);
                    counter = 0;
                    counter++;
                } else {
                    if ($(this).find("td:eq(" + col + ")").text() == oldval) {
                        $(this).find("td:eq(" + col + ")").remove();
                        counter++;
                    } else {
                        $(firstTD).attr("rowSpan", counter);
                        oldval = $(this).find("td:eq(" + col + ")").text();
                        firstTD = $(this).find("td:eq(" + col + ")").get(0);
                        counter = 0;
                        counter++;
                    }
                }
                
                if (index >= $trs.length - 1) {
                    $(firstTD).attr("rowSpan", counter);
                }
                
            });
        }
    
    </script>
    
    <body>
    
        <TABLE id="list_table" BORDER="1">
            <TR>
    
                <TH>&nbsp;&nbsp;&nbsp;</TH>
                <TH>JOB</TH>
                <TH>TOTAL SAL</TH>
    
                <TH>INDEX</TH>
                <TH>EMPNO</TH>
                <TH>ENAME</TH>
                <TH>JOB</TH>
                <TH>MGR</TH>
                <TH>HIREDATE</TH>
                <TH>SAL</TH>
                <TH>COMM</TH>
                <TH>DEPTNO</TH>
            </TR>
            <TR>
                <TD>1</TD>
                <TD>ANALYST</TD>
                <TD>6000</TD>
                <TD>1</TD>
                <TD>7788</TD>
                <TD>SCOTT</TD>
                <TD>ANALYST</TD>
                <TD>7566</TD>
                <TD>4/19/1987</TD>
                <TD>3000.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>1</TD>
                <TD>ANALYST</TD>
                <TD>6000</TD>
                <TD>2</TD>
                <TD>7902</TD>
                <TD>FORD</TD>
                <TD>ANALYST</TD>
                <TD>7566</TD>
                <TD>12/3/1981</TD>
                <TD>3000.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>3</TD>
                <TD>7934</TD>
                <TD>MILLER</TD>
                <TD>CLERK</TD>
                <TD>7782</TD>
                <TD>1/23/1982</TD>
                <TD>1300.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>4</TD>
                <TD>7900</TD>
                <TD>JAMES</TD>
                <TD>CLERK</TD>
                <TD>7698</TD>
                <TD>12/3/1981</TD>
                <TD>950.00</TD>
                <TD>&nbsp;</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>5</TD>
                <TD>7369</TD>
                <TD>SMITH</TD>
                <TD>CLERK</TD>
                <TD>7902</TD>
                <TD>12/17/1980</TD>
                <TD>800.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>6</TD>
                <TD>7876</TD>
                <TD>ADAMS</TD>
                <TD>CLERK</TD>
                <TD>7788</TD>
                <TD>5/23/1987</TD>
                <TD>1100.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>7</TD>
                <TD>7698</TD>
                <TD>BLAKE</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>5/1/1981</TD>
                <TD>2850.00</TD>
                <TD>&nbsp;</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>8</TD>
                <TD>7566</TD>
                <TD>JONES</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>4/2/1981</TD>
                <TD>2975.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>9</TD>
                <TD>7782</TD>
                <TD>CLARK</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>6/9/1981</TD>
                <TD>2450.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>4</TD>
                <TD>PRESIDENT</TD>
                <TD>5000</TD>
                <TD>10</TD>
                <TD>7839</TD>
                <TD>KING</TD>
                <TD>PRESIDENT</TD>
                <TD>&nbsp;</TD>
                <TD>11/17/1981</TD>
                <TD>5000.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>4</TD>
                <TD>SUPER PRESIDENT</TD>
                <TD>5000</TD>
                <TD>10</TD>
                <TD>7839</TD>
                <TD>KING</TD>
                <TD>PRESIDENT</TD>
                <TD>&nbsp;</TD>
                <TD>11/17/1981</TD>
                <TD>5000.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>11</TD>
                <TD>7844</TD>
                <TD>TURNER</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>9/8/1981</TD>
                <TD>1500.00</TD>
                <TD>0.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>12</TD>
                <TD>7654</TD>
                <TD>MARTIN</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>9/28/1981</TD>
                <TD>1250.00</TD>
                <TD>1400.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>13</TD>
                <TD>7521</TD>
                <TD>WARD</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>2/22/1981</TD>
                <TD>1250.00</TD>
                <TD>500.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>14</TD>
                <TD>7499</TD>
                <TD>ALLEN</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>2/20/1981</TD>
                <TD>1600.00</TD>
                <TD>300.00</TD>
                <TD>30</TD>
            </TR>
        </TABLE>
    
    </body>
    </html>
    WrongMergeTD.html

    > 写得不好怎么办?卷土重来呗

    于是,重新写了两个公用方法来合并单元格。

    一个是合并相邻值相同的单元格;

    另外一个是合并指定序号的单元格,比如2-5,6-8,是“合并第2个至第5个单元格、第6个和至第8个单元格”。

    这俩方法将“获取需要合并的TD元素”的动作交由方法调用者,只负责对入参单元格作对应的合并。

    JS

    /**
     * Meger cells with same text
     * @param $tds TDs jquery object
     * @param type row/col
     */
    function mergeCell4SameText($tds, type) {
        
        var oldval;
        var firstTD;
        var counter = 0;
        $tds.each(function(index) {
            
            if (index == 0) {
                oldval = $(this).text();
                firstTD = $(this).get(0);
                counter = 0;
                counter++;
            } else {
                if ($(this).text() == oldval) {
                    $(this).remove();
                    counter++;
                } else {
                    if (type == 'col') {
                        $(firstTD).attr("rowSpan", counter);
                    } else if (type == 'row') {
                        $(firstTD).attr("colSpan", counter);
                    }
                    
                    oldval = $(this).text();
                    firstTD = $(this).get(0);
                    counter = 0;
                    counter++;
                }
            }
            
            if (index >= $tds.length - 1) {
                
                if (type == 'col') {
                    $(firstTD).attr("rowSpan", counter);
                } else if (type == 'row') {
                    $(firstTD).attr("colSpan", counter);
                }
                
            }
            
        });
    }
    
    /**
     * Meger cells by the parameters "index"
     * @param $tds TDs jquery object
     * @param type row/col
     * @param index for example, 0-1,2-5,6-8,10-13
     */
    function mergeCellByIndex($tds, type, index) {
        
        var indexArrs = index.split(',');
        
        var fromTo;
        var from;
        var to;
        
        for (var i in indexArrs) {
            fromTo = indexArrs[i];
            
            from = new Number(fromTo.split('-')[0]);
            to = new Number(fromTo.split('-')[1]);
            
            for (var j = 1 + from; j <= to; j++) {
                $($tds.get(j)).remove();
            }
            
            if (type == 'col') {
                $($tds.get(from)).attr("rowSpan", to - from + 1);
            } else if (type == 'row') {
                $($tds.get(from)).attr("colSpan", to - from + 1);
            }
            
        }
        
    }
    tdmerger

    调用的页面(HTML代码,较长):

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    
    <script type="text/javascript" src="../js/jquery.js"></script>
    <script type="text/javascript" src="../js/tdmerger.js"></script>
    <script type="text/javascript">
        $().ready(function() {
    
            $col1tds = $("table tr td:nth-child(1)");
            $col2tds = $("table tr td:nth-child(2)");
            $col3tds = $("table tr td:nth-child(3)");
            
            mergeCellByIndex($col1tds, 'col', '0-1,2-5,6-8,10-13');
            mergeCellByIndex($col2tds, 'col', '0-1,2-5,6-8,10-13');
            mergeCellByIndex($col3tds, 'col', '0-1,2-5,6-8,10-13');
            
            /*
            $row2tds = $("table tr:eq(2) td");
            mergeCellByIndex($row2tds, 'row', '6-11');
            */
    
        });
    
    </script>
    
    <body>
    
        <TABLE BORDER="1">
            <TR>
    
                <TH>&nbsp;&nbsp;&nbsp;</TH>
                <TH>JOB</TH>
                <TH>TOTAL SAL</TH>
    
                <TH>INDEX</TH>
                <TH>EMPNO</TH>
                <TH>ENAME</TH>
                <TH>JOB</TH>
                <TH>MGR</TH>
                <TH>HIREDATE</TH>
                <TH>SAL</TH>
                <TH>COMM</TH>
                <TH>DEPTNO</TH>
            </TR>
            <TR>
                <TD>1</TD>
                <TD>ANALYST</TD>
                <TD>6000</TD>
                <TD>1</TD>
                <TD>7788</TD>
                <TD>SCOTT</TD>
                <TD>ANALYST</TD>
                <TD>7566</TD>
                <TD>4/19/1987</TD>
                <TD>3000.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>1</TD>
                <TD>ANALYST</TD>
                <TD>6000</TD>
                <TD>2</TD>
                <TD>7902</TD>
                <TD>FORD</TD>
                <TD>ANALYST</TD>
                <TD>7566</TD>
                <TD>12/3/1981</TD>
                <TD>3000.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>3</TD>
                <TD>7934</TD>
                <TD>MILLER</TD>
                <TD>CLERK</TD>
                <TD>7782</TD>
                <TD>1/23/1982</TD>
                <TD>1300.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>4</TD>
                <TD>7900</TD>
                <TD>JAMES</TD>
                <TD>CLERK</TD>
                <TD>7698</TD>
                <TD>12/3/1981</TD>
                <TD>950.00</TD>
                <TD>&nbsp;</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>5</TD>
                <TD>7369</TD>
                <TD>SMITH</TD>
                <TD>CLERK</TD>
                <TD>7902</TD>
                <TD>12/17/1980</TD>
                <TD>800.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>2</TD>
                <TD>CLERK</TD>
                <TD>4150</TD>
                <TD>6</TD>
                <TD>7876</TD>
                <TD>ADAMS</TD>
                <TD>CLERK</TD>
                <TD>7788</TD>
                <TD>5/23/1987</TD>
                <TD>1100.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>7</TD>
                <TD>7698</TD>
                <TD>BLAKE</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>5/1/1981</TD>
                <TD>2850.00</TD>
                <TD>&nbsp;</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>8</TD>
                <TD>7566</TD>
                <TD>JONES</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>4/2/1981</TD>
                <TD>2975.00</TD>
                <TD>&nbsp;</TD>
                <TD>20</TD>
            </TR>
            <TR>
                <TD>3</TD>
                <TD>MANAGER</TD>
                <TD>8275</TD>
                <TD>9</TD>
                <TD>7782</TD>
                <TD>CLARK</TD>
                <TD>MANAGER</TD>
                <TD>7839</TD>
                <TD>6/9/1981</TD>
                <TD>2450.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>4</TD>
                <TD>PRESIDENT</TD>
                <TD>5000</TD>
                <TD>10</TD>
                <TD>7839</TD>
                <TD>KING</TD>
                <TD>PRESIDENT</TD>
                <TD>&nbsp;</TD>
                <TD>11/17/1981</TD>
                <TD>5000.00</TD>
                <TD>&nbsp;</TD>
                <TD>10</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>11</TD>
                <TD>7844</TD>
                <TD>TURNER</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>9/8/1981</TD>
                <TD>1500.00</TD>
                <TD>0.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>12</TD>
                <TD>7654</TD>
                <TD>MARTIN</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>9/28/1981</TD>
                <TD>1250.00</TD>
                <TD>1400.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>13</TD>
                <TD>7521</TD>
                <TD>WARD</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>2/22/1981</TD>
                <TD>1250.00</TD>
                <TD>500.00</TD>
                <TD>30</TD>
            </TR>
            <TR>
                <TD>5</TD>
                <TD>SALESMAN</TD>
                <TD>5600</TD>
                <TD>14</TD>
                <TD>7499</TD>
                <TD>ALLEN</TD>
                <TD>SALESMAN</TD>
                <TD>7698</TD>
                <TD>2/20/1981</TD>
                <TD>1600.00</TD>
                <TD>300.00</TD>
                <TD>30</TD>
            </TR>
        </TABLE>
    
    </body>
    </html>
    mergeTD

    对于合并单元格,这两种方式都不太满意,可是,也想不到更好的方法对此操作作封装。

    如果童靴有更好的方法,请指点!!

  • 相关阅读:
    【NYOJ】[168]房间安排
    【NYOJ】[168]房间安排
    【POJ】[3253]Fence Repair
    【POJ】[3253]Fence Repair
    【杭电】[2111]Saving HDU
    【杭电】[2111]Saving HDU
    【杭电】[3635]Dragon Balls
    【杭电】[3635]Dragon Balls
    [leetcode]159. Longest Substring with At Most Two Distinct Characters至多包含两种字符的最长子串
    [leetcode]3. Longest Substring Without Repeating Characters无重复字母的最长子串
  • 原文地址:https://www.cnblogs.com/nick-huang/p/3884836.html
Copyright © 2011-2022 走看看