0
点赞
收藏
分享

微信扫一扫

可视化编辑json数据——json editor

宁静的猫 2022-06-20 阅读 134

最近开发了一个chrome插件,需要找一个轻量级的可视化编辑json的组件。当然使用ace这一类组件是完全可以的,但是个人感觉比较重量。于是查阅了一些资料,整理如下。

对于一个json字符串,通过javascript的如下方法可以很方便的对其格式化:

var jsonObj = JSON.parse(json_val)   //把json字符串转为json对象
var formattedStr = JSON.stringify(jsonObj, null, 4);

将formattedStr字符串可以输出到textarea组件中。这种方法简单粗暴,缺少了json的折叠、高亮等功能;更进一步,可以通过以下两个组件实现可视化展示json数据:

  • jquery.json-viewer.js:jquery的一个可视化json插件,项目地址​​https://www.jqueryscript.net/other/jQuery-Plugin-For-Easily-Readable-JSON-Data-Viewer.html​​
  • JSONView:可视化json组件,github地址:​​https://github.com/yesmeck/jquery-jsonview​​

以上,是如何可视化展示json数据的方法,而这次的需求不光是要可视化展示,还要可以编辑json数据,于是在github上找到了这个代码(​​https://github.com/dblate/jquery.json-editor​​​),在demo页面(​​https://dblate.github.io/jquery.json-editor/​​)中试用了一下,感觉已经满足了我的需求(可编辑+小巧)。

阅读源码发现该项目的代码非常简单,简单到几乎没有任何实现,完全依赖底层的jquery.json-viewer.js库(上面已介绍)。所以,接下来我们就直接使用jquery.json-viewer.js这个库来实现可以编辑的json格式化组件。

先上例子:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/jquery.json-viewer@1.4.0/json-viewer/jquery.json-viewer.css" rel="stylesheet">
</head>
<style type="text/css">
#json-display {
border: 1px solid #000;
margin: 0;
padding: 8px 15px;
min-height: 300px;
background: #1c2833;
color: #fff;
}
</style>
<body>
<div style="padding: 40px 20px 0px 20px;">
<div>
<pre id="json-display" contenteditable="true"></pre>
</div>
<br>
<input type="button" id="format_btn" value="格式化" onclick="format_btn();" />
</div>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery.json-viewer@1.4.0/json-viewer/jquery.json-viewer.js"></script>
<script>
$(document).ready(function(){
var jsonObj = {"a":1,"b":"test"};
$("#json-display").jsonViewer(jsonObj,{withQuotes: true});//格式化展示
});
function format_btn() {
var jsonval = $("#json-display").text();
var jsonObj = JSON.parse(jsonval); //把json字符串转为json对象
$("#json-display").jsonViewer(jsonObj,{withQuotes: true});//格式化展示
}
</script>
</body>
</html>

效果如下图:

可视化编辑json数据——json editor_json

1、如何做到的可编辑?

contenteditable 属性是 HTML5 中的新属性;该属性规定元素内容是否可编辑。那么通过该数据,就可以对jquery.json-viewer.js中的<pre>节点进行编辑了。例如:

<!DOCTYPE HTML>
<html>
<body>

<div contenteditable="true">这是一段可编辑的段落。请试着编辑该文本。</div>

</body>
</html>

2、复制时去掉格式:

通过contenteditable属性,将<pre>变成可编辑的,当把网页中的json数据复制到编辑框中,发现会把格式也复制进去,例如:

可视化编辑json数据——json editor_html_02

解决方案:

$(document).ready(function(){
//paste clean format
$("#json-display").on("paste", function (e) {
textInit(e)
});
});

function textInit(e) {
e.preventDefault();
var text;
var clp = (e.originalEvent || e).clipboardData;
if (clp === undefined || clp === null) {
text = window.clipboardData.getData("text") || "";
if (text !== "") {
if (window.getSelection) {
var newNode = document.createElement("span");
newNode.innerHTML = text;
window.getSelection().getRangeAt(0).insertNode(newNode);
} else {
document.selection.createRange().pasteHTML(text);
}
}
} else {
text = clp.getData('text/plain') || "";
if (text !== "") {
document.execCommand('insertText', false, text);
}
}
}

 3、遇到问题一:

输入如下的json数据进行格式化,格式化后c节点的value值没有被引号包裹:

{"a":1,"b":"test","c":"http://test.com"}

 结果如下:(这样会破坏了原始json数据)

可视化编辑json数据——json editor_jquery_03

说明:对于json数据结构的标准,key是必须要有双引号;value则根据类型,如果是字符串需要使用双引号。json-viewer.js库可以通过如下属性,设置key是否使用引号:

$("#json-display").jsonViewer(jsonObj,{withQuotes: true});

解决方法:

从json-viewer.js源码可以发现,源码中会判断value是否是url,如果是则直接输出

可视化编辑json数据——json editor_json_04

 所以,可以直接修改源码,添加上双引号。

 4、遇到问题二:

输入如下json数据进行格式化,格式化后extra节点的value值也被当作了json,再次被格式化:

{"a":1,"extra":"{\n  \"circles\" : [\n    \"史莱姆\"\n  ],\n  \"tags\" : [\n    \"危险的她\"\n  ],\n  \"topics\" : [\n    \"好久不见\"\n  ]\n}"}

结果如下:(破坏了原始json 数据)

可视化编辑json数据——json editor_jquery_05

解决方法: 

使用JSON.stringify方法保留字符串中的\n等,然后直接输出:

if (typeof json === 'string') {
// Escape tags and quotes
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');

if (options.withLinks && isUrl(json)) {
html += '<a href="' + json + '" class="json-string" target="_blank">"' + json + '"</a>';
} else {
json = JSON.stringify(json);//保留字符串中的\n等
let len = json.length -1;
if (json.indexOf("\"") ===0 && json.lastIndexOf("\"") ===len) {
html += '<span class="json-string">' + json + '</span>';
} else {
html += '<span class="json-string">"' + json + '"</span>';
}
}
}

效果:

可视化编辑json数据——json editor_html_06

5、遇到问题三:

格式化后,可以点击左侧的三角进行折叠,这时该如何获取<pre>节点下的原始json数据?

1)json-viewer原理:

从源码可以看到json-viewer格式化展示json数据的原理是,将json数据结构解析,放到<ul><li>中,对于每个ul节点可以进行toggle操作,从而实现了折叠效果。折叠后,json-viewer会增加一个<a>标签,记录折叠的字节点个数,如下:

可视化编辑json数据——json editor_html_07

2)如何获取纯文本数据?

在jquery中,获取“容器”中的内容有两种方式:html()和text(),前者返回的数据中包括html标签,后者获取的是纯文本数据。text()方法的原理是,使用正则表达式,去除所有html标签。

function delHtmlTag(str) {
return str.replace(/<[^>]+>/g,"");//去掉所有的html标记
}

3)json-viewer格式化json后如何获取纯json数据?

我们知道,当折叠互后json-viewer会增加<a>标签,即使使用text()方法获取到纯文本数据,这里面也包含了“n items”的字符串,那么该如何去除掉这些字符串呢?

思路:使用jquery拷贝<pre>节点,然后remove那些折叠的节点数据(<a href="" class="json-placeholder">2 items</a>)

$("#format_btn").click(function(){
var my_json_val = $("#json-display").clone(false);
my_json_val.find("a.json-placeholder").remove();
var json_val = my_json_val.text();
if(json_val){
try {
var jsonObj = JSON.parse(json_val); //把json字符串转为json对象
$("#json-display").jsonViewer(jsonObj,{withQuotes: true});
} catch(err) {
$("#json-display").html(json_val+"<br><font color='red'>"+err.message+"</font>");
}
}
});

6、如何让<pre>保持一个初始高度,并随着内容增加而变化?

可以使用min-height属性。​


举报

相关推荐

0 条评论