如何使用jQuery克隆表中的两列

Jos*_*Son 5 jquery clone html-table

我试图使用jQuery从表中克隆2列到新表.源表如下:

<table id="sourceT">
    <tr>
        <td>Col 1</td>
        <td>Col 2</td>
        <td>Col 3</td>
    </tr>
    <tr>
        <td>Col 1 - value</td>
        <td>Col 2 - value</td>
        <td>Col 3 - value</td>
    </tr>
</table>
<table id="targetT"></table>
Run Code Online (Sandbox Code Playgroud)

我试过的是,

$("#sourceT").find("tr > td:nth-child(1), tr > td:nth-child(2)").each(function () {
    $("#targetT").append($("<tr></tr>").append($(this).clone()));
});
Run Code Online (Sandbox Code Playgroud)

我只想将第一列和第二列复制到新表中

<table id="targetT">
    <tr>
        <td>Col 1</td>
        <td>Col 2</td>
   </tr>
    <tr>
        <td>Col 1 - value</td>
        <td>Col 2 - value</td>
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

但是使用那些jquery,我只能得到如下;

<table id="targetT">
    <tr>
        <td>Col 1</td>
    </td>
    <tr>
        <td>Col 1 - value</td>
    </td>
    <tr>
        <td>Col 2</td>
    </td>
    <tr>
        <td>Col 2 - value</td>
    </td>
</table>
Run Code Online (Sandbox Code Playgroud)

我不是试图从源表循环所有的tr和td.Coz,我的源表将超过数千行和超过50列.任何人都有任何想法?

nnn*_*nnn 6

我可能会这样做:

var $target = $("#targetT");
$("#sourceT tr").each(function() {
    var $tds = $(this).children(),
        $row = $("<tr></tr>");
    $row.append($tds.eq(0).clone()).append($tds.eq(1).clone()).appendTo($target);
});
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/HwzQg/

也就是说,循环遍历源表的每一行,只需复制所需的列.这样,所需列是否相邻无关紧要,如果需求发生变化,很容易更改代码以复制更多列.实际上,您可以轻松地将其封装在一个函数中,该函数将源表和目标表作为参数以及要复制的列号列表:

function copyColumns(srcTableId, targetTableId) {
    var colNos = [].slice.call(arguments,2),
        $target = $("#" + targetTableId);
    $("#" + srcTableId + " tr").each(function() {
        var $tds = $(this).children(),
            $row = $("<tr></tr>");
        for (var i = 0; i < colNos.length; i++)
            $row.append($tds.eq(colNos[i]).clone());
        $row.appendTo($target);
    });
}

copyColumns("sourceT", "targetT", 0, 1);
// NOTE that this allows you to easily re-order the columns as you copy them:
copyColumns("sourceT", "targetT", 1, 0, 2);
Run Code Online (Sandbox Code Playgroud)

这用于arguments让您将任意数量的列号作为单独的参数,但当然您可以将其修改为接受列号数组.什么对你有用.

演示:http://jsfiddle.net/HwzQg/1/

"我不是试图从源表中循环所有tr和td.因为,我的源表将超过数千行和超过50列."

我不担心源表的大小.代码首先获得您需要的结果,然后在性能不佳时优化代码.你展示的代码有点隐含地循环遍历原始表两次td:nth-child(1)然后td:nth-child(2).

  • 我还创建了一个函数来根据您的初始答案执行此操作.我看到你有同样的想法.http://jsfiddle.net/5MQJV/ (2认同)

jfr*_*d00 5

你可以用这个:

$("#sourceT tr").each(function(index) {
    var newRow = $("<tr></tr>");
    $(this).find("td:lt(2)").each(function() {
        newRow.append($(this).clone());
    })
    $("#targetT").append(newRow);
});
Run Code Online (Sandbox Code Playgroud)

工作演示:http://jsfiddle.net/jfriend00/JRwVN/

或者更紧凑的版本,使用更多链接而不是.each():

$("#sourceT tr").each(function(index) {
    var newRow = $("<tr></tr>");
    $(this).find("td:lt(2)").clone().appendTo(newRow);
    $("#targetT").append(newRow);
});
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/jfriend00/QRVfE/

找到所需列的任何代码(无论选择器如何)都将在表的每一行中查找.走DOM(这是这些选择器操作所做的)并不是一个缓慢的操作.什么是慢速操作是创建新的DOM对象并将它们插入到DOM中,并且在您的情况下无法避免这种情况.

如果性能是超级关键的(在攻击它之前你应该证明它实际上是一个问题),实际上有时候创建一个巨大的HTML字符串并将其全部放入DOM中而不是插入单独的DOM对象会更快.

如果性能至关重要,那么构建HTML字符串的版本在Chrome,IE10和Firefox中的速度似乎要快20%.它的工作原理如下:

var newTable = "";
$("#sourceT tr").each(function(index) {
    newTable += "<tr>";
    $(this).find("td:lt(2)").each(function() {
        newTable += "<td>" + this.innerHTML + "</td>";
    });
    newTable += "</tr>";
});
$("#targetT").html(newTable);
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/jfriend00/MDAKe/

并且,jsperf比较了最后两种方式:http://jsperf.com/table-copy

我确信还有其他方法可以提高性能(通常jQuery本身并不能为您提供运行速度最快的代码).


事实证明,删除所有jQuery使其大约快8-12倍(取决于浏览器):

var newTable = "";
var rows = document.getElementById("sourceT").rows;
for (var i = 0, len = rows.length; i < len; i++) {
    var cells = rows[i].cells;
    newTable += "<tr><td>" + cells[0].innerHTML + "</td><td>" + cells[1].innerHTML + "</td></tr>";
}
document.getElementById("targetT").innerHTML = newTable;
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/jfriend00/7AJk2/

  • @JoshuaSon - 我的jsperf中的数组版本并不比使用字符串快.几年前,它可能会,但字符串已经加速了很多.在jsperf中,你必须在每次测试之前清理在DOM中插入的东西.jsperf有一个地方可以做到这一点.这是名为"定义所有测试的设置"的框.你可以看看我是如何做到的. (2认同)