代码文本对比-前端工具
代码文本对比
很多时候,我们可能有那种前端代码对比、文本对比的功能
方式一(纯js实现)
- 效果图
- 主要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>
- 主要js
// data.appBefore--变更前数据
const bf = data.appBefore.replace(new RegExp("<", "gm"), "<").replace(new RegExp(">", "gm"), ">");
// data.appAfter--变更后数据
// 这里replace是把数据中的<、>替换成<、> 如果想要pre标签中展示html、xml类型代码数据的话
const af = data.appAfter.replace(new RegExp("<", "gm"), "<").replace(new RegExp(">", "gm"), ">");
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文件不要落迁移了
其他问题注意自己看控制台检查
代码文本对比-前端工具相关推荐
- notepad数据对比插件_如何使用NotePad++的compare插件进行文本对比,来研究下吧
对于程序员而言,进行文本(程序代码)对比是家常便饭,而文本编辑器Notepad++里的Compare插件,可以帮助程序员高效地完成文本对比工作. 下面,小编就来教大家如何安装及使用NotePad++软 ...
- 代码强力对比,就用这7个工具!
点击上方蓝色"终端研发部",选择"设为星标" 学最好的别人,做最好的我们 来源:搜云技术库 在程序开发的过程中,程序员会经常对源代码以及库文件进行代码对比,在这 ...
- Winform,RichTextBox,Json文本对比工具
在工作中,有的时候需要做一些Json对比的需求,通过肉眼去找到不一样的地方 当然,现在有很多可以做对比的小工具,比如Beyond Compare 但是这个有个弊端,如果对比的时候是个Json字符串,没 ...
- debug内exe文件复制到桌面无法打开_Diffinity.轻量级的文件|文本对比工具
Diffinity是一款非常轻量级的文件与文本对比的小工具软件,软件的安装包仅475KB,同时支持高亮显示.插入显示.集成到资源管理器(右键菜单)等,非常的方便实用.并且最近的一次更新是在9月初,生命 ...
- Vue前端文本对比DIFF
介绍 前端文本比对找了几个库: 分别是: CodeMirror.DiffMatchPatch.Mergely.vue-code-diff,最后选择用:vue-code-diff 源码工程地址:DIFF ...
- UltraCompare 22:文本对比工具 Mac版
UltraCompare中文版还可以实现文本对比,二进制文档对比,以及实现进行对比的文档间的不同点的整合.极大地提高了工作效率! 会议 使用UltraCompare的会话功能,您可以在多个选项卡中打开 ...
- java 文本差异对比高亮工具
分享一下(基于谷歌文本比对工具)转载: https://blog.csdn.net/qq_34062622/article/details/105436727
- 文本对比,文本差异并排对比显示实现
目录 前言 方法一:java + html实现 1..准备 2..后端实现 3..测试和效果 方法二:Mergely纯javascript实现 1.Mergely使用示例 2.效果图 3.使用示例中用 ...
- 14W 行代码量的前端页面长什么样
作者:sigmaliu,腾讯文档 AlloyTeam 开发工程师 0. 前言 腾讯文档列表页在不久前经历了一次完全重构后,首屏速度其实已经是不错.但是我们仍然可以引入 SSR 来进一步加快速度.这篇文 ...
最新文章
- 新信号!阿里 AI 工程师趋于年轻化,高端AI人才严重短缺
- 金豆芽:硬件创业我更看好细分领域
- ubuntu运行navicat没有反应的解决方法
- 采样次数不同平均值不一样_网络推广采取的方式不同,效果也不一样
- [zz]libev 简介
- sunplus 8202v iop源代码阅读笔记——2
- Linux Netcat command – The swiss army knife of net
- BIN文件和HEX文件差异
- 微信小程序视频自定义进度条
- 保研后,你们都怎么样了?
- 技能梳理24@stm32+阿里云+nbiot+dht11+bh1750+土壤湿度传感器+oled
- 【MATLAB】使用“蒙特卡罗(Monter Carlo)”算法计算不规则图形的面积
- 阿里技术专家的编程方法论:如何写出一手漂亮的代码?
- DataType--类型基础
- Dilate Gated Convolutional Neural Network
- CSS之浮动/BFC/清除浮动(十二)
- 计算机图形学(四)几何变换_5_三维空间的几何变换_1_三维平移
- 关于Win10 64位Cadence16.6中OrCAD Capture CIS导网表出现ERROR无效指针的解决办法
- PT展现场直击,广和通5G模组点亮数字化未来
- Unity如何驱动打印机打印