一个纯Js的文本比较工具,下面是html的代码,只完成了简单的2个文本比较,显示出修改的内容


感觉比较好的应该是像git上那样,做了哪些修改都会显示出来的那种。
例如这样:




然而事实是只 做一个这样的:

<!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:#00DB00;";
	}
	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>