可以进行每一行的对比,比如单独行的增加、删除,以及每一行中有些单词的不同
效果如图:
- 使用 npm install diff-match-patch 下载
- 使用的主要方法是:主要使用doDiff匹配左右两边的差异化,直接返回差异化内容显示页面,如果想去看的话可以打印看一下,下面直接上代码
doDiff(leftText, rightText) {
// Go ahead and map nbsp;
var unicodeCharacter = String.fromCharCode(this.unicodeRangeStart + this.mapLength);
this.tagMap[' '] = unicodeCharacter;
this.tagMap[unicodeCharacter] = ' ';
this.mapLength++;
var diffableLeft = this.convertHtmlToDiffableString(leftText);
var diffableRight = this.convertHtmlToDiffableString(rightText);
var diffs = this.dmp.diff_main(diffableLeft, diffableRight);
this.dmp.diff_cleanupSemantic(diffs);
var diffOutput = "";
for (var x = 0; x < diffs.length; x++) {
diffs[x][1] = this.insertTagsForOperation(diffs[x][1], diffs[x][0]);
diffOutput += this.convertDiffableBackToHtml(diffs[x][1]);
}
// console.log("diffOutput=======" + diffOutput);
this.diffOutput = diffOutput;
},
convertHtmlToDiffableString(htmlString) {
var diffableString = "";
if(htmlString == null || htmlString.length == 0){
return diffableString;
}
htmlString = htmlString.replace(/ /g, this.tagMap[' ']);
var offset = 0;
while (offset < htmlString.length) {
var tagStart = htmlString.indexOf("<", offset);
if (tagStart < 0) {
diffableString += htmlString.substr(offset);
break;
} else {
var tagEnd = htmlString.indexOf(">", tagStart);
if (tagEnd < 0) {
// Invalid HTML
// Truncate at the start of the tag
console.log("Invalid HTML. String will be truncated.");
diffableString += htmlString.substr(offset, tagStart - offset);
break;
}
var tagString = htmlString.substr(tagStart, tagEnd + 1 - tagStart);
// Is this tag already mapped?
var unicodeCharacter = this.tagMap[tagString];
if (unicodeCharacter === undefined) {
// Nope, need to map it
unicodeCharacter = String.fromCharCode(this.unicodeRangeStart + this.mapLength);
this.tagMap[tagString] = unicodeCharacter;
this.tagMap[unicodeCharacter] = tagString;
this.mapLength++;
}
// At this point it has been mapped, so now we can use it
diffableString += htmlString.substr(offset, tagStart - offset);
diffableString += unicodeCharacter;
offset = tagEnd + 1;
}
}
return diffableString;
}
insertTagsForOperation(diffableString, operation) {
// Don't insert anything if these are all tags
var n = -1;
do {
n++;
} while (diffableString.charCodeAt(n) >= this.unicodeRangeStart + 1);
if (n >= diffableString.length) {
return diffableString;
}
var openTag = "";
var closeTag = "";
if (operation === 1) {
openTag = "<ins style='color: green;'>";
closeTag = "</ins>";
} else if (operation === -1) {
openTag = "<del style='color: red;'>";
closeTag = "</del>";
} else {
return diffableString;
}
var outputString = openTag;
var isOpen = true;
for (var x = 0; x < diffableString.length; x++) {
if (diffableString.charCodeAt(x) < this.unicodeRangeStart) {
// We just hit a regular character. If tag is not open, open it.
if (!isOpen) {
outputString += openTag;
isOpen = true;
}
outputString += diffableString[x];
} else {
// We just hit one of our mapped unicode characters. Close our tag.
if (isOpen) {
outputString += closeTag;
isOpen = false;
}
outputString += diffableString[x];
}
}
if (isOpen) outputString += closeTag;
return outputString;
}
convertDiffableBackToHtml(diffableString) {
var htmlString = "";
for (var x = 0; x < diffableString.length; x++) {
var charCode = diffableString.charCodeAt(x);
if (charCode < this.unicodeRangeStart) {
htmlString += diffableString[x];
continue;
}
var tagString = this.tagMap[diffableString[x]];
if (tagString === undefined) {
// We somehow have a character that is above our range but didn't map
// Do we need to add an upper bound or change the range?
htmlString += diffableString[x];
} else {
htmlString += tagString;
}
}
return htmlString;
}