【问题标题】:How to show diff of two html tables using javascript?如何使用 javascript 显示两个 html 表的差异?
【发布时间】:2013-05-31 04:26:01
【问题描述】:

我有一组已更改的表格数据。现在我在两个 html 表中并排呈现了两个数据。现在我想突出显示已更改的列,就像在 svn 文件差异中一样。

我尝试这样做,但我需要使其递归但不确定如何:

function CompareTables(table1, table2) {
    var instHasChange = false;
    for (var i = 0; i < table1.rows.length; i++) {

        var changes = RowExists(table2, table1.rows[i].cells[0].innerHTML, table1.rows[i].cells[1].innerHTML);
        if (!changes[0]) {
            table1.rows[i].style.backgroundColor = "yellow";
            instHasChange = true;
        } else if (changes[1]) {
            table1.rows[i].style.backgroundColor = "yellow";
            instHasChange = true;
        }
    }
    for (var i = 0; i < table2.rows.length; i++) {
        var changes = RowExists(table1, table2.rows[i].cells[0].innerHTML, table2.rows[i].cells[1].innerHTML);
        if (!changes[0]) {
            table2.rows[i].style.backgroundColor = "yellow";
            instHasChange = true;
        } else if (changes[1]) {
            table2.rows[i].style.backgroundColor = "yellow";
            instHasChange = true;
        }
    }
    return instHasChange;
}

function RowExists(table, columnName, columnValue) {

    var hasColumnOrChange = new Array(2);
    hasColumnOrChange[0] = false;
    hasColumnOrChange[1] = false;
    for (var i = 0; i < table.rows.length; i++) {
        if (table.rows[i].cells[0].innerHTML == columnName) {
            hasColumnOrChange[0] = true;
            if (table.rows[i].cells[1].innerHTML != columnValue)
                hasColumnOrChange[1] = true;
        }
    }

    return hasColumnOrChange;
}

上面的代码只有在这个表里面没有内表的情况下才有效(我们用这种方式表示db子表的数据)

请帮忙! 谢谢!

编辑

我发现了一些对单个表有效的代码,但不确定如何使其适用于表中的表。把代码贴在这里

    function highLightDiffList() {
        for (var k = 0; k < 8; k++) {
            var mkrTname = 'table3' + k;
            var actTname = 'table4' + k;
            var makerTr = document.getElementById(mkrTname).childNodes;
            var actualTr = document.getElementById(actTname).childNodes;
            var makerStateLen = makerTr.length;
            var actualStateLen = actualTr.length;
            var actualState = 1;
            var makerState = 1;
            if (makerStateLen > 1)
                makerState = makerTr.item(1).childNodes.item(0).childNodes;
            if (actualStateLen > 1)
                actualState = actualTr.item(1).childNodes.item(0).childNodes;
            var makerTh = document.getElementById(mkrTname).getElementsByTagName("TH").length;
            var minLen;
            var maxLen;
            var flag;
            if (makerStateLen > actualStateLen) {
                minLen = actualStateLen;
                maxLen = makerStateLen;
                flag = 1;
            } else {
                minLen = makerStateLen;
                maxLen = actualStateLen;
                flag = 2;
            }
            for (var i = 1; i < minLen; i++) {
                for (var j = 0; j < makerTh; j++) {
                    if (makerTr.item(i).childNodes.item(0).childNodes.item(j).innerHTML != actualTr.item(i).childNodes.item(0).childNodes.item(j).innerHTML) {
                        makerTr.item(i).childNodes.item(0).childNodes.item(j).style.backgroundColor = document.getElementById('cColor').value;
                        actualTr.item(i).childNodes.item(0).childNodes.item(j).style.backgroundColor = document.getElementById('cColor').value;
                    }
                }
            }
            for (var i = minLen; i < maxLen; i++) {
                for (var j = 0; j < makerTh; j++) {
                    if (flag == 1)
                        makerTr.item(i).style.backgroundColor = document.getElementById('adColor').value;
                    if (flag == 2)
                        actualTr.item(i).style.backgroundColor = document.getElementById('adColor').value;
                }
            }
        }
    }

    function highLightDiff() {
        for (var j = 0; j < 6; j++) {
            var mkrTname = 'table1' + j;
            var actTname = 'table2' + j;

            var makerTr = document.getElementById(mkrTname);
            var actualTr = document.getElementById(actTname);

            var makerStateLen = makerTr.childNodes.item(1).childNodes.length;
            var actualStateLen = actualTr.childNodes.item(1).childNodes.length;

            var makerState = makerTr.childNodes.item(1).childNodes;
            var actualState = actualTr.childNodes.item(1).childNodes;
            for (var i = 1; i < makerStateLen; i++) {
                if (makerState.item(i).childNodes.item(1).innerHTML != '' && actualState.item(i).childNodes.item(1).innerHTML == '') {
                    makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
                    actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
                } else {
                    if (makerState.item(i).childNodes.item(1).innerHTML == '' && actualState.item(i).childNodes.item(1).innerHTML != '') {
                        makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
                        actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('adColor').value;
                    } else {
                        if (makerState.item(i).childNodes.item(1).innerHTML != actualState.item(i).childNodes.item(1).innerHTML) {
                            makerState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('cColor').value;
                            actualState.item(i).childNodes.item(1).style.backgroundColor = document.getElementById('cColor').value;
                        }
                    }
                }
            }
        }
    }

内表的创建方式如下:

<table>
    <tbody>
        <tr>
            <td>
                <div>
                    <table>
                        <tbody>
                            <tr>
                                <td>

【问题讨论】:

  • 如果你愿意接受 jQuery,Table To JSON 擅长从 HTML 表构建哈希。从那里,您只需要比较生成的 javascript 对象并相应地更新表格 CSS

标签: javascript html css diff html-table


【解决方案1】:
function CompareTables(table1, table2) {
    var instHasChange = false;
    for (var i = 0; i < table1.rows.length; i++) {
        if (table1.rows[i].cells[0].innerHTML.indexOf('div') != -1) {
            //call CompareTables with inner table
            CompareTables(table1.rows[i].cells[0].childNodes[0].childNodes[0], table2);
        }
        else {
            var changes = RowExists(table2, table1.rows[i].cells[0].innerHTML, table1.rows[i].cells[1].innerHTML);
            if (!changes[0]) {
                table1.rows[i].style.backgroundColor = "yellow";
                instHasChange = true;
            } else if (changes[1]) {
                table1.rows[i].style.backgroundColor = "yellow";
                instHasChange = true;
            }
        }
    }
    return instHasChange;
}

function RowExists(table, columnName, columnValue) {

    var hasColumnOrChange = new Array(2);
    hasColumnOrChange[0] = false;
    hasColumnOrChange[1] = false;
    for (var i = 0; i < table.rows.length; i++) {
        if (table.rows[i].cells[0].innerHTML.indexOf('div') != -1) {
            //call RowExists with inner table
            hasColumnOrChange = RowExists(table.rows[i].cells[0].childNodes[0].childNodes[0], columnName, columnValue);
        }
        else {
            if (table.rows[i].cells[0].innerHTML == columnName) {
                hasColumnOrChange[0] = true;
                if (table.rows[i].cells[1].innerHTML != columnValue)
                    hasColumnOrChange[1] = true;
            }
        }
        //finish for loop if name was found
        if (hasColumnOrChange[0] == true)
            break;
    }

    return hasColumnOrChange;
}

未经测试,但应该可以工作。如果与内部表不完全匹配,则可能只需要添加或删除另一个 .childNodes[0](或 firstChild)。
然后你只需要调用 CompareTables(table1, table2) 两次。一次使用 (table1, table2),一次使用 (table2, table1)。

【讨论】:

    【解决方案2】:

    您可能会发现在内部表格的 HTML 上进行实际的文本差异比较容易,然后使用其中的信息来推导哪些单元格已更改/添加/等。例如,如果您获取每个表格的原始 HTML(通过 innerHTML 或其他方式提取),请确保每个开始标记和结束标记都在其自己的行上,然后您可以查找新的/修改的行并将它们映射回基于行号。

    有几个javascriptdiffimplementations。您还可以查看Dom-diff,它是您可以使用的 DOM 级别差异系统的实现。

    【讨论】:

    • 不错的建议,但我无法使用新行技术,因为表格 html 是由第三方生成的。您提到的 diff 实现也非常好,但我只需要基本级别的添加/更新/删除分类,以便我可以适当地突出相应的 td,它们似乎非常复杂(如 char to char diff)
    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 2019-01-11
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多