在文本框中美化JSON数据

84

我搜索了这个特定的主题,并没有找到类似的内容。如果有,请关闭此页面并给出链接。

我正在创建一个 JSON 数据 API 模拟器。我希望用户能够将 JSON 对象请求复制并粘贴到文本区域中,在发送到服务器之前还可以修改它。

问题是,JSON 对象的复制和粘贴通常会导致额外的空格,并且不会正确对齐,即使使用 pre 标签也无济于事。我还希望应用良好的颜色方案来显示键和值。

我已经看到了插件、其他问题和代码片段,但它们并不适用于文本区域,因为在编辑模式下会显示所有的 HTML 标签。是否有一种方法可以在编辑模式下保持样式而不显示所有的 HTML 标签呢?我想用 JavaScript 或 jQuery 从头开始编写它。

6个回答

198
语法高亮是有难度的,但可以查看这个示例,以漂亮的方式打印在文本区域中输入的json对象。请注意,JSON必须有效才能正常工作。(使用开发控制台捕获错误。)检查jsLint是否为有效的JSON。
HTML:
<textarea id="myTextArea" cols=50 rows=10></textarea>
<button onclick="prettyPrint()">Pretty Print</button>

js:

function prettyPrint() {
    var ugly = document.getElementById('myTextArea').value;
    var obj = JSON.parse(ugly);
    var pretty = JSON.stringify(obj, undefined, 4);
    document.getElementById('myTextArea').value = pretty;
}

首先尝试一些简单的输入,例如: {"a":"hello","b":123}

JSON 的简单格式化输出可以很容易地实现。尝试使用以下 JavaScript 代码: (这里是 jsFiddle 的链接)

// arbitrary js object:
var myJsObj = {a:'foo', 'b':'bar', c:[false,2,null, 'null']};

// using JSON.stringify pretty print capability:
var str = JSON.stringify(myJsObj, undefined, 4);

// display pretty printed object in text area:
document.getElementById('myTextArea').innerHTML = str;

对于这个HTML:

<textarea id="myTextArea" cols=50 rows=25></textarea>

查看JSON.stringify文档


14
JSON.stringify(obj, undefined, 4) 这就是我要找的。谢谢。 - Rohidas Kadam
是的,这就是JSON.stringify()的结构:stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string - Akhil

10
很晚回答,但是现代的做法是使用密切缩进参数。
我通常会选择:
JSON.stringify(myData, null, 4);
以下是代码定义,它很好地解释了它:
stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
/**
 * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
 * @param value A JavaScript value, usually an object or array, to be converted.
 * @param replacer An array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified.
 * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
 */

4

在解析步骤中,您只需要对文本区域的内容进行JSON.parse操作,并处理来自错误输入的任何错误。

至于格式化部分,使用JSON.stringify(blob, undefined, 2)即可。或者,如果您需要颜色,则可以使用用React编写的简单的JSON格式/颜色组件:

const HighlightedJSON = ({ json }: Object) => {
  const highlightedJSON = jsonObj =>
    Object.keys(jsonObj).map(key => {
      const value = jsonObj[key];
      let valueType = typeof value;
      const isSimpleValue =
        ["string", "number", "boolean"].includes(valueType) || !value;
      if (isSimpleValue && valueType === "object") {
        valueType = "null";
      }
      return (
        <div key={key} className="line">
          <span className="key">{key}:</span>
          {isSimpleValue ? (
            <span className={valueType}>{`${value}`}</span>
          ) : (
            highlightedJSON(value)
          )}
        </div>
      );
    });
  return <div className="json">{highlightedJSON(json)}</div>;
};

在这个 CodePen 中可以看到它的工作原理: https://codepen.io/benshope/pen/BxVpjo

希望这有所帮助!


4
如果你是jquery的粉丝,你也可以使用我编写的这个小插件:

// The plugin
$.fn.json_beautify= function() {
    this.each(function(){
        var el = $(this),
            obj = JSON.parse(el.val()),
            pretty = JSON.stringify(obj, undefined, 4);
        el.val(pretty);
    });
};

// Then use it like this on any textarea
$('textarea').json_beautify();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<textarea id="myTextArea" cols=50 rows=5>{"name":"John","age":30}</textarea>
<textarea id="myTextArea2" cols=50 rows=5>{"name":"Bob","age":55}</textarea>

更新:将代码更改为多选元素。


2
我认为普通的文本区域无法实现这个功能。您可以创建一个透明的文本区域,覆盖在包含样式代码的 div 上面。用户仍然可以输入并与输入交互(并触发相关的表单事件),而您可以在用户可视化的 div 中显示语法高亮。 (参见 Textarea that can do syntax highlighting on the fly?
至于 JSON 格式化,我会向文本区域添加自定义事件,以便当用户键入或粘贴内容时,将其通过 JavaScript JSON prettifier 进行处理(参见 How can I pretty-print JSON using JavaScript?),然后相应地重新填充 div 和文本区域。

2

以下是一个递归函数,用于在对象被多次字符串化时返回该对象:

const jsonPrettify = (json) => {
  if (typeof json === 'object' && json !== null) {
    const pretty = JSON.stringify(json, undefined, 4);
    return pretty;
  }

  try {
    const obj = JSON.parse(json);
    return jsonPrettify(obj);
  } catch (e) {
    return json;
  }
};

这个递归的吗? - zfj3ub94rf576hc4eegm
@Luke 谢谢!错过了一些代码行! - Ghasem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接