javascript - jQuery 合并表行,但考虑以前的列

标签 javascript jquery html merge

我有一张 html 表格。该表使用通用的 tr 和 td ……并制作一个包含六列和可变行数的动态表。

如果给定的表看起来像这样:

|column 1|column 2|column 3|column 4|column 5|column 6|
-------------------------------------------------------
|  John  |  Green |apples  |February|  cow   |   23   |
-------------------------------------------------------
|  John  |  Red   |Oranges |February|  lion  |   18   |
-------------------------------------------------------
|  John  |  Blue  |apples  |February|  cow   |   45   |
-------------------------------------------------------
|  Mary  |  Blue  |oranges |  April |  cow   |   23   |
-------------------------------------------------------
|  Mary  |  Blue  |apples  |   May  |  dog   |   49   |
-------------------------------------------------------
|  Mary  |  green |apples  |  June  |  cat   |   67   |
-------------------------------------------------------
|  Mary  |  red   |apples  |  June  |  mouse |   32   |
-------------------------------------------------------

当我运行以下 javascript 时:

function MergeCommonRows(table, columnIndexToMerge) {
previous = null;
cellToExtend = null;
table.find("td:nth-child(" + columnIndexToMerge + ")").each(function() {
    jthis = $(this);
    content = jthis.text()
    if (previous == content && content !== "") {
        jthis.remove();
        if (cellToExtend.attr("rowspan") == undefined) {
            cellToExtend.attr("rowspan", 2);
        }
        else {
            currentrowspan = parseInt(cellToExtend.attr("rowspan"));
            cellToExtend.attr("rowspan", currentrowspan + 1);
        }
    }
    else {
        previous = content;
        cellToExtend = jthis;
    }
});
}

制作了下表:

|column 1|column 2|column 3|column 4|column 5|column 6|
-------------------------------------------------------
|        |  Green |apples  |        |  cow   |   23   |
         ------------------         -------------------
|  John  |  Red   |Oranges |February|  lion  |   18   |
         ------------------         -------------------
|        |        |apples  |        |        |   45   |
---------         ------------------         ----------
|        |  Blue  |oranges | April  |  cow   |   23   |
                  ------------------         ----------
|  Mary  |        |        |  May   |        |   49   |
          --------         ----------------------------
|        |  green | apples |  June  |  cat   |   67   |
          --------         ----------------------------
|        |  red   |        |  July  |  mouse |   32   |
-------------------------------------------------------

现在,javascript 的工作原理是我确实需要合并行,如上表所示。第一列合并得很好。列中的其他区域也是如此。我唯一的问题出现在第 2 列和第 5 列等区域。现在重申一下,这些表将始终是动态生成的,所以我不能以静态方式处理它。但是......第 2 列中的“蓝色”和第 5 列中的“牛”的合并超过了第 1 列中的关联值。相反,我想要一个这样的表:

|column 1|column 2|column 3|column 4|column 5|column 6|
-------------------------------------------------------
|        |  Green |apples  |        |  cow   |   23   |
         ------------------         -------------------
|  John  |  Red   |Oranges |February|  lion  |   18   |
         ------------------         -------------------
|        |  Blue  |apples  |        |  cow   |   45   |
-------------------------------------------------------
|        |  Blue  |oranges | April  |  cow   |   23   |
                  ------------------         ----------
|  Mary  |        |        |  May   |        |   49   |
          --------         ----------------------------
|        |  green | apples |  June  |  cat   |   67   |
          --------         ----------------------------
|        |  red   |        |  July  |  mouse |   32   |
-------------------------------------------------------

在上表中,“blue”和“cow”的合并单元格是分开的,因为它前面的单元格在那里结束了它们的 rowspan。这无论如何都会发生。如果第二列中的一个单元格碰巧跨越多行,那么任何后续列都不能有 rowspans 延伸超过它。希望我所描述的足够清楚。我在问...我该如何修改我的 javascript 才能达到这种效果?

最佳答案

如果只有第一列应该是其余列的“分隔线”,那么您可以使用数组来存储第一列的行“分隔符”。

此外,您的功能无权工作。当元素在循环内被 removed 时,被移除元素上方的每个元素的索引立即下移以填充 DOM 索引间隙(因此在下一次迭代中跳过被移除元素之后的元素)。您可以使用“递减”循环或简单地隐藏 td

function MergeCommonRows(table) {
    var firstColumnBrakes = [];
    // iterate through the columns instead of passing each column as function parameter:
    for(var i=1; i<=table.find('th').length; i++){
        var previous = null, cellToExtend = null, rowspan = 1;
        table.find("td:nth-child(" + i + ")").each(function(index, e){
            var jthis = $(this), content = jthis.text();
            // check if current row "break" exist in the array. If not, then extend rowspan:
            if (previous == content && content !== "" && $.inArray(index, firstColumnBrakes) === -1) {
                // hide the row instead of remove(), so the DOM index won't "move" inside loop.
                jthis.addClass('hidden');
                cellToExtend.attr("rowspan", (rowspan = rowspan+1));
            }else{
                // store row breaks only for the first column:
                if(i === 1) firstColumnBrakes.push(index);
                rowspan = 1;
                previous = content;
                cellToExtend = jthis;
            }
        });
    }
    // now remove hidden td's (or leave them hidden if you wish):
    $('td.hidden').remove();
}

$('.button').click(function(){
    MergeCommonRows($('#tbl'));
});
table {
    border-collapse: collapse;
}

th, td {
    border: 1px solid black;
    padding:5px;
    text-align: center;
}

.hidden{
    display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table id=tbl>
    <thead>
        <tr>
            <th>column 1</th>
            <th>column 2</th>
            <th>column 3</th>
            <th>column 4</th>
            <th>column 5</th>
            <th>column 6</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>John</td>
            <td>Green</td>
            <td>apples</td>
            <td>February</td>
            <td>cow</td>
            <td>23</td>
        </tr>
        <tr>
            <td>John</td>
            <td>Red</td>
            <td>Oranges</td>
            <td>February</td>
            <td>lion</td>
            <td>18</td>
        </tr>
        <tr>
            <td>John</td>
            <td>Blue</td>
            <td>apples</td>
            <td>February</td>
            <td>cow</td>
            <td>45</td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>Blue</td>
            <td>Oranges</td>
            <td>April</td>
            <td>cow</td>
            <td>23</td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>Blue</td>
            <td>apples</td>
            <td>May</td>
            <td>cow</td>
            <td>49</td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>green</td>
            <td>apples</td>
            <td>June</td>
            <td>cat</td>
            <td>67</td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>red</td>
            <td>apples</td>
            <td>June</td>
            <td>mouse</td>
            <td>32</td>
        </tr>
    </tbody>
</table>

<p><button class=button>Merge Rows</button></p>

关于javascript - jQuery 合并表行,但考虑以前的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40860803/

相关文章:

javascript - 如何通过ajax追加div

javascript - 如何从按钮移动父级 div

javascript - Safari 上的动态隐藏选择列表

javascript - 将 jQuery.html() 的值加在一起?

html - 如何从左到右制作圆形进度条的动画?

javascript - 如何从数组中选择json项

javascript - 在 Y 轴上拉伸(stretch) div 元素

javascript - 如何使用 javascript 为谷歌分析创建点击事件

javascript - 比较 JSON 返回的参数值

javascript - 用 jquery 替换文档