【转】纯JavaScript实现文本对比

<!doctype html>
<html>

<head>
    <title>文本比较工具</title>
    <style type="text/css">
        * {
            padding: 0px;
            margin: 0px;
        }

        html,
        body {
            overflow-y: hidden;
        }

        .edit_div {
            border: 1px solid #CCCCCC;
            overflow: auto;
            position: relative;
        }

        .edit_div textarea {
            resize: none;
            background: none repeat scroll 0 0 transparent;
            border: 0 none;
            width: 100%;
            height: 200px;
            overflow-y: scroll;
            position: absolute;
            left: 0px;
            top: 0px;
            z-index: 2;
            font-size: 18px;
            white-space: pre-wrap;
            word-wrap: break-word;
            word-break: break-all;
        }

        .edit_div pre {
            overflow-y: scroll;
            white-space: pre-wrap;
            word-wrap: break-word;
            word-break: break-all;
            width: 100%;
            height: 200px;
            text-align: left;
            color: #ffffff;
            z-index: 1;
            font-size: 18px;
        }
    </style>
</head>

<body>
    <table style="width:100%">
        <tr>
            <td style="width:50%">
                <div class="edit_div">
                    <pre id="edit_pre_1"></pre>
                    <textarea id="edit_textarea_1" onscroll="test1_scroll()" oninput="textchange()" onpropertychange="textchange()"></textarea>
                </div>
            </td>
            <td style="width:50%">
                <div class="edit_div">
                    <pre id="edit_pre_2"></pre>
                    <textarea id="edit_textarea_2" onscroll="test2_scroll()" oninput="textchange()" onpropertychange="textchange()"></textarea>
                </div>
            </td>
        </tr>
    </table>
    <script type="text/javascript">
        function test1_scroll() {
            document.getElementById("edit_pre_1").scrollTop = document.getElementById("edit_textarea_1").scrollTop;
            document.getElementById("edit_pre_2").scrollTop = document.getElementById("edit_pre_1").scrollTop;
            document.getElementById("edit_textarea_2").scrollTop = document.getElementById("edit_textarea_1").scrollTop;
        }

        function test2_scroll() {
            document.getElementById("edit_pre_2").scrollTop = document.getElementById("edit_textarea_2").scrollTop;
            document.getElementById("edit_pre_1").scrollTop = document.getElementById("edit_pre_2").scrollTop;
            document.getElementById("edit_textarea_1").scrollTop = document.getElementById("edit_textarea_2").scrollTop;
        }

        function textchange() {
            var op = eq({
                value1: document.getElementById("edit_textarea_1").value,
                value2: document.getElementById("edit_textarea_2").value
            });
            document.getElementById("edit_pre_1").innerHTML = op.value1 + "\r\n";
            document.getElementById("edit_pre_2").innerHTML = op.value2 + "\r\n";
        }

        function eq(op) {
            if (!op) {
                return op;
            }
            if (!op.value1_style) {
                op.value1_style = "background-color:#FEC8C8;";
            }
            if (!op.value2_style) {
                op.value2_style = "background-color:#FEC8C8;";
            }
            if (!op.eq_min) {
                op.eq_min = 3;
            }
            if (!op.eq_index) {
                op.eq_index = 5;
            }
            if (!op.value1 || !op.value2) {
                return op;
            }
            var ps = {
                v1_i: 0,
                v1_new_value: "",
                v2_i: 0,
                v2_new_value: ""
            };
            while (ps.v1_i < op.value1.length && ps.v2_i < op.value2.length) {
                if (op.value1[ps.v1_i] == op.value2[ps.v2_i]) {
                    ps.v1_new_value += op.value1[ps.v1_i].replace(/</g, "<").replace(">", ">");
                    ps.v2_new_value += op.value2[ps.v2_i].replace(/</g, "<").replace(">", ">");
                    ps.v1_i += 1;
                    ps.v2_i += 1;
                    if (ps.v1_i >= op.value1.length) {
                        ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i).replace(/</g, "<").replace(
                            ">", ">") + "</span>";
                        break;
                    }
                    if (ps.v2_i >= op.value2.length) {
                        ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i).replace(/</g, "<").replace(
                            ">", ">") + "</span>";
                        break;
                    }
                } else {
                    ps.v1_index = ps.v1_i + 1;
                    ps.v1_eq_length = 0;
                    ps.v1_eq_max = 0;
                    ps.v1_start = ps.v1_i + 1;
                    while (ps.v1_index < op.value1.length) {
                        if (op.value1[ps.v1_index] == op.value2[ps.v2_i + ps.v1_eq_length]) {
                            ps.v1_eq_length += 1;
                        } else if (ps.v1_eq_length > 0) {
                            if (ps.v1_eq_max < ps.v1_eq_length) {
                                ps.v1_eq_max = ps.v1_eq_length;
                                ps.v1_start = ps.v1_index - ps.v1_eq_length;
                            }
                            ps.v1_eq_length = 0;
                            break; //只寻找最近的
                        }
                        ps.v1_index += 1;
                    }
                    if (ps.v1_eq_max < ps.v1_eq_length) {
                        ps.v1_eq_max = ps.v1_eq_length;
                        ps.v1_start = ps.v1_index - ps.v1_eq_length;
                    }

                    ps.v2_index = ps.v2_i + 1;
                    ps.v2_eq_length = 0;
                    ps.v2_eq_max = 0;
                    ps.v2_start = ps.v2_i + 1;
                    while (ps.v2_index < op.value2.length) {
                        if (op.value2[ps.v2_index] == op.value1[ps.v1_i + ps.v2_eq_length]) {
                            ps.v2_eq_length += 1;
                        } else if (ps.v2_eq_length > 0) {
                            if (ps.v2_eq_max < ps.v2_eq_length) {
                                ps.v2_eq_max = ps.v2_eq_length;
                                ps.v2_start = ps.v2_index - ps.v2_eq_length;
                            }
                            ps.v1_eq_length = 0;
                            break; //只寻找最近的
                        }
                        ps.v2_index += 1;
                    }
                    if (ps.v2_eq_max < ps.v2_eq_length) {
                        ps.v2_eq_max = ps.v2_eq_length;
                        ps.v2_start = ps.v2_index - ps.v2_eq_length;
                    }
                    if (ps.v1_eq_max < op.eq_min && ps.v1_start - ps.v1_i > op.eq_index) {
                        ps.v1_eq_max = 0;
                    }
                    if (ps.v2_eq_max < op.eq_min && ps.v2_start - ps.v2_i > op.eq_index) {
                        ps.v2_eq_max = 0;
                    }
                    if ((ps.v1_eq_max == 0 && ps.v2_eq_max == 0)) {
                        ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1[ps.v1_i].replace(/</g, "<").replace(">",
                            ">") + "</span>";
                        ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2[ps.v2_i].replace(/</g, "<").replace(">",
                            ">") + "</span>";
                        ps.v1_i += 1;
                        ps.v2_i += 1;

                        if (ps.v1_i >= op.value1.length) {
                            ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i).replace(/</g, "<").replace(
                                ">", ">") + "</span>";
                            break;
                        }
                        if (ps.v2_i >= op.value2.length) {
                            ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i).replace(/</g, "<").replace(
                                ">", ">") + "</span>";
                            break;
                        }
                    } else if (ps.v1_eq_max > ps.v2_eq_max) {
                        ps.v1_new_value += "<span style='" + op.value1_style + "'>" + op.value1.substr(ps.v1_i, ps.v1_start - ps.v1_i).replace(
                            /</g, "<").replace(">", ">") + "</span>";
                        ps.v1_i = ps.v1_start;
                    } else {
                        ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2.substr(ps.v2_i, ps.v2_start - ps.v2_i).replace(
                            /</g, "<").replace(">", ">") + "</span>";
                        ps.v2_i = ps.v2_start;
                    }
                }
            }
            op.value1 = ps.v1_new_value;
            op.value2 = ps.v2_new_value;
            return op;
        }

        function settextheight() {
            var heigth = (document.documentElement.clientHeight - 6) + "px"
            document.getElementById("edit_pre_1").style.height = heigth;
            document.getElementById("edit_textarea_1").style.height = heigth;
            document.getElementById("edit_pre_2").style.height = heigth;
            document.getElementById("edit_textarea_2").style.height = heigth;
        }
        window.onload = function () {
            settextheight();
            window.onresize = function () {
                settextheight();
            }
        }
    </script>
</body>

</html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值