手记

自己写JSON编辑器 JSON校验工具

作者:娇娇jojo

时间:2018年1月22日

下一篇:自己写代码对比工具

时间过得好快,一下子就2018年了,想起好久没写博客,不觉有些浪费了时光,今天便来写一篇。

JSON是个伟大的东西,各处都用得到,既方便也纠结。用的溜的人那就没啥说的了,但也有用的不溜的或者想偷懒的人,那JSON也算是一个小小的槛吧。怎么说呢,就比如说有的人到现在连JSON的正确格式都写不对,也有人写对了但并没有自信自己是否写对,那这时候就需要一个校验工具来检验JSON格式的正确性。既然有了校验,那格式化工具怎么能少,再随着需求的增加,我要是能随时随地能编辑JSON就好了。正好,一切都是向着自动化的方向发展,JSON的自动化也不例外,层出不穷的JSON工具也随之出来,大抵功能也就我说的那几样,JSON本身就不是复杂的东西,用来解析、校验和编辑它的东西自然也是越简洁越好。

正好最近自己公司也有这需求,于是自己就研究了一番,当然自己写会比较浪费时间,于是就在网上寻寻觅觅,终于发现了一款还不错的JSON编辑器组件 —— JSON Editor,然后自己倒持倒持,自个儿看着还挺舒服,用着也还行,就决定和大家分享一下,让大家也学会自己制作一款属于自己的JSON编辑器。如果会的话就略过,哈哈哈。

先给大家截一张我做的JSON编辑器的图吧。

一、介绍

JSON Editor是一个基于Web的工具。用于查看,编辑和格式化JSON。有多种modes,比如:a tree editor, a code editor, and a plain text editor。

JSON Editor可以用作我们web应用的一个组件。类库可以当做CommonJS模块、AMD模块或者常规JS文件加载。

支持的浏览器: Chrome, Firefox, Safari, Opera, Internet Explorer 9+.

二、安装
npm install jsoneditor

可以npm安装,也可以直接引用cdn,或者下载下来再引用。

// 为了在我们的web应用中实现JSONEditor,我们需要载入css和js文件
<link href="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.js"></script>

// 获取更多详细的错误信息
<script src="https://cdn.bootcss.com/ace/1.2.9/ace.js"></script>

//上面提到支持多种modes,而其中的code mode比较特别,需要依赖于Ace editor, JSON Editor comes with a custom built version of Ace containing the ace modules ace.js, ext-searchbox.js, mode-json.js, theme-textmate.js, and a custom theme theme-jsoneditor.js。除了载入ace.js之外,我们还需要在js代码中设置mode,就像下面给出的实例中所示。
<script src="https://cdn.bootcss.com/jsonlint/1.6.0/jsonlint.min.js"></script>
三、使用
<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>JSON编辑器</title>
        <link href="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.css" rel="stylesheet">
        <style>
            body,
            div,
            ul,
            li,
            p {
                margin: 0;
                padding: 0;
                list-style: none;
            }

            body {
                padding-top: 20px;
            }

            .flex {
                display: flex;
                justify-content: center;
                align-content: center;
            }

            .btn-box {
                margin: 0 20px;
                padding-top: 100px;
            }

            .btn-box button {
                padding: 10px 20px;
                border: 1px solid #a4a4a4;
                border-radius: 5px;
                background: #eee;
            }

            .btn-box .json-btn {
                margin-bottom: 20px;
            }

            .code-btn-box {
                text-align: right;
                margin-top: 20px;
            }

            .code-btn-box button {
                padding: 10px 20px;
                border: 1px solid #a4a4a4;
                border-radius: 5px;
                background: #eee;
            }

            .code-btn-box .save-btn {
                border: 1px #f60 solid;
                background: #ffc88b;
                color: #f15214;
                margin-left: 20px;
            }
        </style>
    </head>

    <body>
        <div class="flex">
            <div >
                <p class="title-text">code</p>
                <div id="codeEditor" ></div>
                <div class="code-btn-box">
                    <button id="compact" class="compact-btn" type="button">压缩</button>
                    <button id="format" class="format-btn" type="button">格式化</button>
                    <button id="save" class="save-btn" type="button">保存</button>
                </div>
            </div>

            <ul class="btn-box">
                <li>
                    <button id="jsonBtn" class="json-btn" type="button">视图化 >></button>
                </li>
                <li>
                    <button id="codeBtn" type="button"><< 代码化</button>
                </li>
            </ul>

            <div >
                <p class="title-text">JSON</p>
                <div id="jsonEditor" ></div>
            </div>
        </div>
    </body>
    <script src="https://cdn.bootcss.com/jsoneditor/5.13.1/jsoneditor.min.js"></script>
    <script src="https://cdn.bootcss.com/ace/1.2.9/ace.js"></script>
    <script src="https://cdn.bootcss.com/jsonlint/1.6.0/jsonlint.min.js"></script>
    <script>
        var codeEditor = document.getElementById("codeEditor");
        var jsonEditor = document.getElementById("jsonEditor");
        var jsonBtn = document.getElementById("jsonBtn");
        var codeBtn = document.getElementById("codeBtn");
        var compact = document.getElementById("compact");
        var format = document.getElementById("format");
        var save = document.getElementById("save");

        //初始化编辑器模式
        var codeOptions = {
            mode: 'code',
            modes: ['code'],
            onError: function(err) {
                alert(err.toString());
            }
        };

        var jsonOptions = {
            mode: 'tree',
            modes: ['code', 'form', 'text', 'tree', 'view'],
            onError: function(err) {
                alert(err.toString());
            }
        };

        //初始化编辑器内容
        var codeEditor = new JSONEditor(codeEditor, codeOptions, {
            "a": 1
        });
        var jsonEditor = new JSONEditor(jsonEditor, jsonOptions, {
            "a": 1
        });

        //视图化
        jsonBtn.onclick = function() {
            try {
                var codeContent = codeEditor.get();
                if(codeContent == "") {
                    alert("请输入JSON数据后再转换!");
                } else {
                    jsonEditor.set(codeContent);
                }
            } catch(e) {
                alert("JSON数据有误!");
            }

        }

        //代码化
        codeBtn.onclick = function() {
            try {
                var jsonContent = jsonEditor.get();
                codeEditor.set(jsonContent);
            } catch(e) {
                alert("JSON数据有误!");
            }
        }

        //压缩
        compact.onclick = function() {
            try {
                var codeContent = codeEditor.getText();
                if(codeContent == "") {
                    alert("请输入JSON数据后再转换!");
                } else {
                    codeContent = JSON.stringify(eval('(' + codeContent + ')'))
                    codeEditor.setText(codeContent);
                }
            } catch(e) {
                alert("JSON数据有误!");
            }
        }

        //格式化
        format.onclick = function() {
            try {
                var codeContent = codeEditor.getText();
                if(codeContent == "") {
                    alert("请输入JSON数据后再转换!");
                } else {
                    codeContent = JSON.stringify(eval('(' + codeContent + ')'), null, 2);
                    codeEditor.setText(codeContent);
                }
            } catch(e) {
                alert("JSON数据有误!");
            }
        }

        //保存
        save.onclick = function() {
            try {
                var codeContent = codeEditor.getText();
                if(codeContent == "") {
                    alert("请输入JSON数据后再转换!");
                } else {
                    alert(codeContent);
                }
            } catch(e) {
                alert("JSON数据有误!");
            }
        }
    </script>

</html>
四、API

1、JSONEditor构造函数

JSONEditor(container [, options] [, json])

2、方法 

JSONEditor.collapseAll()

Collapse all fields. Only applicable for mode ‘tree’, ‘view’, and ‘form’.

JSONEditor.expandAll()

Expand all fields. Only applicable for mode ‘tree’, ‘view’, and ‘form’.

JSONEditor.set(json)

Set JSON data.

JSONEditor.setMode(mode)

Switch mode. Mode code requires the Ace editor.

可选参数:tree, view, form, code, text.

JSONEditor.setName(name)

Set a field name for the root node.

JSONEditor.setText(jsonString)

Set text data in the formatter.

JSONEditor.get()

Get JSON data.

JSONEditor.getName()

Retrieve the current field name of the root node.

JSONEditor.getText()

Get JSON data as string.

从一个JSON对象创建一个格式化字符串:

var formattedString = JSON.stringify(json, null, 2);

从一个JSON对象创建一个压缩字符串:

var compactString = JSON.stringify(json);

从一个字符串创建一个JSON对象:

var json = JSON.parse(string);

3、JSON.stringify 函数

JSON.stringify(value [, replacer] [, space])

 value:必选。 JavaScript 值,通常对象或数组,将转换。

replacer:可选。 转换结果的函数或数组。

如果 replacer 函数,调用 JSON.stringify 函数,传入键值和每个成员。 返回值用于代替原始值。 如果函数返回 undefined,成员被排除。 根对象的关键是空字符串:””

如果 replacer 是数组,因此,只有用键值的成员数组中将转换。 成员变换的顺序与键顺序的数组中。 当 value 参数也是 replacer 数组时,数组被忽略。

space:可选。 添加缩进、空白和换行符来返回值 JSON 文本更便于阅读。

如果省略 space,返回值文本生成,没有任何额外的空白。

如果 space 是数字,则返回值具有空白的文本缩进指定数目在每个级别的。 如果 space 大于 10 时,文本缩进 10 个空白。

如果 space 为非空字符串,如“\t”,返回值文本缩进与字符串的字符在每个级别。

如果 space 为大于 10 个字符的字符串,使用前 10 个字符。

实例:

var continents = new Array();
continents[0] = "Europe";
continents[1] = "Asia";
continents[2] = "Australia";
continents[3] = "Antarctica";
continents[4] = "North America";
continents[5] = "South America";
continents[6] = "Africa";

var jsonText = JSON.stringify(continents, replaceToUpper);

function replaceToUpper(key, value) {
    return value.toString().toUpperCase();
}

//Output:
// "EUROPE,ASIA,AUSTRALIA,ANTARCTICA,NORTH AMERICA,SOUTH AMERICA,AFRICA"

和:

var contact = new Object();
contact.firstname = "Jesper";
contact.surname = "Aaberg";
contact.phone = ["555-0100", "555-0120"];

var memberfilter = new Array();
memberfilter[0] = "surname";
memberfilter[1] = "phone";
var jsonText = JSON.stringify(contact, memberfilter, "\t");
document.write(jsonText);
// Output: 
// { "surname": "Aaberg", "phone": [ "555-0100", "555-0120" ] }
五、绑定事件

注:这部分转自别家的博客。 

根据我的使用,JsonEditor提供了监听内容改变的接口,需要在options中定义。

var container = $("#editor")[0];
var options = {
    mode: 'code',
    error: function (err) {
        alert(err.toString());
    },
    change: function() {
        ......
    }
};
var editor = new JSONEditor(container, options);

如果在change中需要获取editor中内容,会在页面初始化的时候报错:editor还没有声明什么的。如果一定要获取editor内容,我们可以延迟绑定,代码如下:

var container = $("#editor")[0];
var options = {
    mode: 'code',
    error: function (err) {
        alert(err.toString());
    },
    change: function() {

    }
};
var editor = new JSONEditor(container, options);
editor.options.change = function() {
    ....    
}

注意一定要在options中声明change事件,否则不能正常绑定(具体对不对大家可以自行尝试,这里仅提供一个参考)。

7人推荐
随时随地看视频
慕课网APP