代码文本对比

很多时候,我们可能有那种前端代码对比、文本对比的功能

方式一(纯js实现)

  1. 效果图

  1. 主要html

如果想要在线编辑对比可使用textare标签,并自定义监听函数去对比渲染

<style>pre {width: 50%;float: left;}legend {margin-bottom: 0;}
</style>
<body>
<fieldset><legend>升级<span style="color: red">前</span><span style="color: blue">后</span>对比效果</legend><pre id="pre"></pre><pre id="pre2"></pre>
</fieldset>
</body>
  1. 主要js
// data.appBefore--变更前数据
const bf = data.appBefore.replace(new RegExp("<", "gm"), "&lt;").replace(new RegExp(">", "gm"), "&gt;");
// data.appAfter--变更后数据
// 这里replace是把数据中的<、>替换成&lt;、&gt; 如果想要pre标签中展示html、xml类型代码数据的话
const af = data.appAfter.replace(new RegExp("<", "gm"), "&lt;").replace(new RegExp(">", "gm"), "&gt;");
const result = _eq({value1: bf || bf, value2: af || af});// 由于这个对比页面是个弹窗,用到了layui,故此方式渲染数据至html标签中
// result.value1 变更前数据
// result.value2 变更后数据
body.find("#pre").html(result.value1);
body.find("#pre2").html(result.value2);// 核心方法
function _eq(op) {if(!op){return op;}if(!op.value1_style){op.value1_style="background-color:#f9e9e9;text-decoration: line-through;color:red";}if(!op.value2_style){op.value2_style="background-color:#ddeeff;";}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;
}

方式二(使用CodeMirror)

效果图

codemirror使用过程
下载项目

github:https://github.com/codemirror/CodeMirror
官网:https://codemirror.net/

打开找到demo html->merge.html

检查是否有codemirror.js


如果没有可以在一个新目录下运行npm install codemirror
把新安装的codemirror工程下的lib的codemirror.js复制过来

打开页面



本地调整后测试的merge.html代码:

<!DOCTYPE html>
<html lang="UTF-8"><title>CodeMirror: merge view demo</title>
<meta charset="utf-8"/>
<!--<link rel=stylesheet href="../doc/docs.css">--><link rel=stylesheet href="../lib/codemirror.css">
<link rel=stylesheet href="../addon/merge/merge.css">
<link rel="stylesheet" href="../theme/darcula.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../mode/css/css.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script>
<script src="../addon/merge/merge.js"></script>
<style>.CodeMirror {line-height: 1.2;}@media screen and (min-width: 1300px) {article {max-width: 1000px;}#nav {border-right: 499px solid transparent;}}span.clicky {cursor: pointer;background: #d70;color: white;padding: 0 3px;border-radius: 3px;}
</style><article><h2>Compared view</h2><div id=view></div><script>var value, orig1, orig2, dv, panes = 2, highlight = true, connect = "align", collapse = false;function initUI() {if (value == null) return;var target = document.getElementById("view");target.innerHTML = "";dv = CodeMirror.MergeView(target, {value: value,origLeft: panes === 3 ? orig1 : null,orig: orig2,lineNumbers: true,mode: "text/html",theme: 'darcula',revertButtons: false,highlightDifferences: highlight,connect: connect,collapseIdentical: collapse});}function toggleDifferences() {dv.setShowDifferences(highlight = !highlight);}window.onload = function () {value = 'logging:\n' +'  level:\n' +'    root: info\n' +'    org.apache.ibatis: ${LOG_LEVEL:info}\n' +'    io.choerodon: ${LOG_LEVEL:info}\n' +'    org.hzero: ${LOG_LEVEL:info}';// orig1 = "<!doctype html>\n\n" + value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange");orig2 = 'logging:\n' +'  level:\n' +'    root: ${LOG_LEVEL:info}\n' +'    org.apache.ibatis: ${LOG_LEVEL:info}\n' +'    io.choerodon: ${LOG_LEVEL:info}\n' +'    org.hzero: ${LOG_LEVEL:info}\n' +'\n' +'# 新加测试配置\n' +'test:\n' +'  data: test';initUI();let d = document.createElement("div");d.style.cssText = "width: 50px; margin: 7px; height: 14px";dv.editor().addLineWidget(57, d)};function mergeViewHeight(mergeView) {function editorHeight(editor) {if (!editor) return 0;return editor.getScrollInfo().height;}return Math.max(editorHeight(mergeView.leftOriginal()),editorHeight(mergeView.editor()),editorHeight(mergeView.rightOriginal()));}function resize(mergeView) {var height = mergeViewHeight(mergeView);for (; ;) {if (mergeView.leftOriginal())mergeView.leftOriginal().setSize(null, height);mergeView.editor().setSize(null, height);if (mergeView.rightOriginal())mergeView.rightOriginal().setSize(null, height);var newHeight = mergeViewHeight(mergeView);if (newHeight >= height) break;else height = newHeight;}mergeView.wrap.style.height = height + "px";}</script>
</article>
</html>

关于merge.html中参数和函数说明自行查看官网https://codemirror.net/demo/merge.html

集成应用

前面是在源项目中测试,html中js和css都是相对源项目的相对路径

集成在自己项目中,需要改造迁移html、js、css,把这些文件迁过来


html换了个名字compares.html,代码:

<!DOCTYPE html>
<html lang="UTF-8">
<head><title>详情</title><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"><link rel="stylesheet" href="codeMirror/codemirror.css"><link rel="stylesheet" href="codeMirror/merge.css"><link rel="stylesheet" href="codeMirror/darcula.css"><link rel="stylesheet" href="codeMirror/base16-light.css"><style>.CodeMirror {line-height: 1.2;}@media screen and (min-width: 1300px) {article {max-width: 1000px;}#nav {border-right: 499px solid transparent;}}span.clicky {cursor: pointer;background: #d70;color: white;padding: 0 3px;border-radius: 3px;}h2 {color: yellowgreen;}</style></head><body>
<article><h2>Compared view</h2><div id=view></div><!-- 引入组件库 --><script src="libs/jquery.min.js"></script><script src="codeMirror/codemirror.js"></script>
<!--    <script src="src/edit/CodeMirror.js"></script>--><script src="codeMirror/diff_match_patch.js"></script><script src="codeMirror/merge.js"></script><script src="codeMirror/xml.js"></script><script src="codeMirror/javascript.js"></script><script src="codeMirror/htmlmixed.js"></script><script type="text/javascript">let value, orig1, orig2, dv, panes = 2, highlight = true, connect = null, collapse = false;let mainUrl, sv, tv;mainUrl = getQueryString("mainUrl");sv = getQueryString("sv");tv = getQueryString("tv");function getQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return decodeURI(r[2]);return null;}function initUI() {if (value == null) return;var target = document.getElementById("view");target.innerHTML = "";dv = CodeMirror.MergeView(target, {value: value,origLeft: panes === 3 ? orig1 : null,orig: orig2,lineNumbers: true,mode: "text/html",theme: 'base16-light', // darcularevertButtons: false,highlightDifferences: highlight,connect: connect,collapseIdentical: collapse});}function toggleDifferences() {dv.setShowDifferences(highlight = !highlight);}window.onload = function () {$.ajax({type: "GET",url: mainUrl + "&sourceVersion=" + sv + "&targetVersion=" + tv,contentType: "text/plain",success: function (data) {value = data.appBefore || data.pomBefore;orig2 = data.appAfter || data.pomAfter;initUI();},error: function (e) {alert(e.responseText);}});};function mergeViewHeight(mergeView) {function editorHeight(editor) {if (!editor) return 0;return editor.getScrollInfo().height;}return Math.max(editorHeight(mergeView.leftOriginal()),editorHeight(mergeView.editor()),editorHeight(mergeView.rightOriginal()));}function resize(mergeView) {var height = mergeViewHeight(mergeView);for (; ;) {if (mergeView.leftOriginal())mergeView.leftOriginal().setSize(null, height);mergeView.editor().setSize(null, height);if (mergeView.rightOriginal())mergeView.rightOriginal().setSize(null, height);var newHeight = mergeViewHeight(mergeView);if (newHeight >= height) break;else height = newHeight;}mergeView.wrap.style.height = height + "px";}</script>
</article>
</body>
</html>

这里对比的数据是从后端接口查的,可以一开始写成常量查看效果

<link rel="stylesheet" href="codeMirror/darcula.css">
<link rel="stylesheet" href="codeMirror/base16-light.css">

上面表示的是主题,想要更多的主题去源码工程迁移过来

<script src="codeMirror/diff_match_patch.js"></script>

diff_match_patch.js可以使用demo中的外部路径,我这里是下载下来了

codeMirror中的js和css文件不要落迁移了
其他问题注意自己看控制台检查

代码文本对比-前端工具相关推荐

  1. notepad数据对比插件_如何使用NotePad++的compare插件进行文本对比,来研究下吧

    对于程序员而言,进行文本(程序代码)对比是家常便饭,而文本编辑器Notepad++里的Compare插件,可以帮助程序员高效地完成文本对比工作. 下面,小编就来教大家如何安装及使用NotePad++软 ...

  2. 代码强力对比,就用这7个工具!

    点击上方蓝色"终端研发部",选择"设为星标" 学最好的别人,做最好的我们 来源:搜云技术库 在程序开发的过程中,程序员会经常对源代码以及库文件进行代码对比,在这 ...

  3. Winform,RichTextBox,Json文本对比工具

    在工作中,有的时候需要做一些Json对比的需求,通过肉眼去找到不一样的地方 当然,现在有很多可以做对比的小工具,比如Beyond Compare 但是这个有个弊端,如果对比的时候是个Json字符串,没 ...

  4. debug内exe文件复制到桌面无法打开_Diffinity.轻量级的文件|文本对比工具

    Diffinity是一款非常轻量级的文件与文本对比的小工具软件,软件的安装包仅475KB,同时支持高亮显示.插入显示.集成到资源管理器(右键菜单)等,非常的方便实用.并且最近的一次更新是在9月初,生命 ...

  5. Vue前端文本对比DIFF

    介绍 前端文本比对找了几个库: 分别是: CodeMirror.DiffMatchPatch.Mergely.vue-code-diff,最后选择用:vue-code-diff 源码工程地址:DIFF ...

  6. UltraCompare 22:文本对比工具 Mac版

    UltraCompare中文版还可以实现文本对比,二进制文档对比,以及实现进行对比的文档间的不同点的整合.极大地提高了工作效率! 会议 使用UltraCompare的会话功能,您可以在多个选项卡中打开 ...

  7. java 文本差异对比高亮工具

    分享一下(基于谷歌文本比对工具)转载: https://blog.csdn.net/qq_34062622/article/details/105436727

  8. 文本对比,文本差异并排对比显示实现

    目录 前言 方法一:java + html实现 1..准备 2..后端实现 3..测试和效果 方法二:Mergely纯javascript实现 1.Mergely使用示例 2.效果图 3.使用示例中用 ...

  9. 14W 行代码量的前端页面长什么样

    作者:sigmaliu,腾讯文档 AlloyTeam 开发工程师 0. 前言 腾讯文档列表页在不久前经历了一次完全重构后,首屏速度其实已经是不错.但是我们仍然可以引入 SSR 来进一步加快速度.这篇文 ...

最新文章

  1. 新信号!阿里 AI 工程师趋于年轻化,高端AI人才严重短缺
  2. 金豆芽:硬件创业我更看好细分领域
  3. ubuntu运行navicat没有反应的解决方法
  4. 采样次数不同平均值不一样_网络推广采取的方式不同,效果也不一样
  5. [zz]libev 简介
  6. sunplus 8202v iop源代码阅读笔记——2
  7. Linux Netcat command – The swiss army knife of net
  8. BIN文件和HEX文件差异
  9. 微信小程序视频自定义进度条
  10. 保研后,你们都怎么样了?
  11. 技能梳理24@stm32+阿里云+nbiot+dht11+bh1750+土壤湿度传感器+oled
  12. 【MATLAB】使用“蒙特卡罗(Monter Carlo)”算法计算不规则图形的面积
  13. 阿里技术专家的编程方法论:如何写出一手漂亮的代码?
  14. DataType--类型基础
  15. Dilate Gated Convolutional Neural Network
  16. CSS之浮动/BFC/清除浮动(十二)
  17. 计算机图形学(四)几何变换_5_三维空间的几何变换_1_三维平移
  18. 关于Win10 64位Cadence16.6中OrCAD Capture CIS导网表出现ERROR无效指针的解决办法
  19. PT展现场直击,广和通5G模组点亮数字化未来
  20. Unity如何驱动打印机打印

热门文章

  1. 数据仓库:维度分析和指标
  2. 亚麻种子的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  3. hoolilaw特别分享:在美国喝多少酒就算酒驾
  4. python openpyxl创建excel文件,自己选择excel保存的位置
  5. python 获取股市数据 baostock + 画K线图 mpl_finance
  6. ICTCLAS的JNI调用接口说明
  7. 自学Java day12 使用jvav实现链表 从jvav到架构师
  8. C语言——简单图形打印学习
  9. HR 真的会嫌弃面试者跳槽频繁吗?
  10. Overriding managed version 问题解决