梦想这东西和经典一样,不会因为时间而褪色,反而更显珍贵

Javascript 实现JSON format JSON数据格式化工具

2017-5-17 15:20:13 · 947次浏览

Javascript JSON format JSON数据格式化工具

背景:

Lorna.com.cn 工具箱选项,新增JSON数据格式化工具,本文对该源码分享一下实现流程,后续会推出更多的开发者工具。

效果地址: http://www.lorna.com.cn/Tools/JsonFormat

Javascript 实现JSON format JSON数据格式化工具 - Lorna.com.cn

网上其实有很多类似的源代码,比如Chrome 插件的JSON-format格式化工具,大家可以参考下 JSON Formatter 源码地址:
https://github.com/callumlocke/json-formatter

使用JSON.parse检查并且解析字符串

JSON.parse() 方法解析一个JSON字符串,构造由字符串描述的JavaScript值或对象。可以提供可选的reviver函数以在返回之前对所得到的对象执行变换。

使用JSON.parse()解析用户输入的JSON内容。使用该函数免去我们检查用户输入的内容是否正确,如果被解析的JSON字符串是非法的,则会抛出一个异常。

var json = $("#LornajsonTextBox").val();
var jsonObj = null;
try {
    //// 成功解析
    jsonObj = JSON.parse(json);
} catch (e) {
    //// 抛出异常
    console.log(e);
}


分解分析后的Object

循环获取到的jsonObj的每一个元素,通过typeofinstanceof判断Object类型,如果是Object或者Array继续递归调用。

//// 类型枚举
var typeEnum = {
    TYPE_STRING: "string",
    TYPE_INT: "number",
    TYPE_OBJECT: "object",
    TYPE_BOOLEAN: "boolean",
};

/**
* 格式化JSON
* @jsonObj object
* @tabIndex 显示的缩进等级
**/
function formatJson(jsonObj, tabIndex) {
    //// 声明索引,是否数组元素,该jsonobj长度
    var innerhtml = "", idx = 0, isArray = jsonObj instanceof Array, length = 0;
    if (jsonObj != null) {
        length = Object.keys(jsonObj).length;
    }
    //// 遍历对象
    for (var obj in jsonObj) {
        //// 句末是否需要加上逗号
        var isD = idx + 1 != length;
        var preInnerHtml = "";
        ///// 如果是OBJECT类型,继续递归
        if (typeof jsonObj[obj] == typeEnum.TYPE_OBJECT) {
            if (isArray) {
                //// 包装数组-object
                preInnerHtml = getObjectArrayDiv(formatJson(jsonObj[obj], tabIndex + 1), isD);
            } else {
                //// 包装object
                preInnerHtml = getObjectDiv(obj, formatJson(jsonObj[obj], tabIndex + 1), isD);
            }

        } else {
            //// 普通类型直接包装展示
            if (isArray) {
                preInnerHtml = getArrayDiv(jsonObj[obj], isD);
            } else {
                preInnerHtml = getDiv(obj, jsonObj[obj], isD);
            }
        }
        innerhtml += preInnerHtml;
        idx++;
    }
    //// 包装本次的OBJECT
    return getPanel(innerhtml, tabIndex, isArray, length);
}

注意点

  • .length只能获取Array的长度,获取Object类型需要调用Object.keys(jsonObj)

  • JSON.parse对于0.00 double类型的数据会丢失精度

剩余的方法

剩余的方法主要处理节点的包装,缩进类。

//// 包装普通类型
function getDiv(key, value, isD) {
    return "<div>" + getTitleSpan(key) + ":" + getValueSpan(value) + (isD ? "," : "") + "</div>";;
}

//// 包装Object类型
function getObjectDiv(key, value, isD) {
    return "<div>" + getTitleSpan(key) + ":" + value + (isD ? "," : "") + "</div>";;
}

//// 包装数组内对象
function getObjectArrayDiv(value, isD) {
    return "<div>" + value + (isD ? "," : "") + "</div>";;
}

//// 包装数组
function getArrayDiv(value, isD) {
    return "<div>" + getValueSpan(value) + (isD ? "," : "") + "</div>";;
}

//// 包装Key
function getTitleSpan(value) {
    return "<span class='key'>\"" + value + "\"</span>";
}

//// 包装Value
function getValueSpan(value) {
    var type = typeof value;

    switch (type) {
        case typeEnum.TYPE_STRING:
            return "<span class='value_string'>\"" + value + "\"</span>";
        case typeEnum.TYPE_INT:
            return "<span class='value_int'>" + value + "</span>";
        case typeEnum.TYPE_BOOLEAN:
            return "<span class='value_bool'>" + value + "</span>";
    }
    return "error";
}

//// 包装object
function getPanel(innerHtml, tabIndex, isArray, index) {
    if (isArray) {
        return "<span class=\"\"><i>-</i>[</span><div class=\"tab_" + tabIndex + "\">" + innerHtml + "</div><label class=\"tips\">Array <span class='tips_math'>" + index + "<span></label><span>]</span>";
    } else {
        return "<span class=\"\"><i>-</i>{</span><div class=\"tab_" + tabIndex + "\">" + innerHtml + "</div><label class=\"tips\">Object{...}</label><span>}</span>";
    }
}

//// 缩进事件
function folding() {
    var text = $(this).text();
    if (text == "-") {
        $(this).text("+");
        $(this).parent().parent().find("div").hide();
        $(this).parent().parent().find("label").show();
    } else {
        $(this).text("-");
        $(this).parent().parent().find("div").show();
        $(this).parent().parent().find("label").hide();
    }

}

写在最后

1.本文是Lorna的笔记源码,如果你觉得以上代码及说明存在问题或者可以改进的地方,请留言告诉我,非常感谢!


与本文相关的文章推荐

没有找到文章~~