纯JS文本比较工具

时间:2021-10-25 11:49:57

前段时间由于工作需要写了一个纯JS文本比较工具

在这里与大家分享下

算法有待优化,还希望大家多多指教

先上效果图:

纯JS文本比较工具

奉上源码(把源码保存为html格式的文件就可以直接运行了):

 <!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,"&lt;").replace(">","&gt;");
ps.v2_new_value += op.value2[ps.v2_i].replace(/</g,"&lt;").replace(">","&gt;");
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,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</span>";
ps.v2_new_value += "<span style='" + op.value2_style + "'>" + op.value2[ps.v2_i].replace(/</g,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</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,"&lt;").replace(">","&gt;") + "</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>

纯JS文本比较工具源码