将 JSON 数据格式输出至页面上

更新日期: 2019-08-11阅读: 3.5k标签: 数据

JSON 是一种轻量级的数据交换格式,它有键值对集合(js 中的对象)和数组两种结构。 JSON 是一个通用的格式,在前后端语言中都能跟该 JSON 打交道。有时候我们需要将 JSON 格式输入至页面展示的需求,其中还需要保持一定的索引,那么该如何实现呢?


使用

我们将对象转为 JSON 字符串时会经常使用 JSON.stringify 这个 api,其实该方法就内置有格式化的参数:

var userInfo = {name: 'anran758',github: 'https://github.com/anran758'};
var info = JSON.stringify(userInfo, null, 2);

console.log(info);
// "{↵  "name": "anran758",↵  "github": "https://github.com/anran758"↵}"

在上面的代码中,我们第一个参数( value )传入了一个需要序列化的对象。第二个参数是 replacer ,用以对属性转换和处理,由于我们不需要额外的处理,因此传入一个 null ;第三个参数则是空格索引的个数,封顶是 10 , 0 或不传则没有空格。

在控制台打印出信息后,我们可以看的出来格式化的数据是带换行符,并且有缩进的格式。接下来我们就要考虑如何输出到页面中。


输出

只要学过 html 的朋友都知道,我们直接将数据输入至 HTML 中,空格缩进会被浏览器给忽略掉的。因此不能输入到 <div> 中。这时候又想到, JSON 格式实际上也算是代码的一种,那能不能输入至雷士代码块的标签中呢?答案是可以的。

HTML 中有两个标签可以展示源代码: <pre> 和 <code> 。它们之间不同之处在于:

  • <pre> 表示预定义 格式文本 ,按照原文件中的编排,以等宽字体的形式展现出来, 文本中的空白符(比如空格和换行符)都会显示出来 。
  • <code> 则是呈现一段计算机代码,它以浏览器的默认等宽字体显示, 但并不一定会完整呈现原来的格式 。

这些标签知识实际上算是比较冷门的知识,或许远古的面试题会考这种知识点,平时很少会遇到。但是如果你经常使用 markdown 的话,那么这些标签在 markdown 中有不同的别名:

比如 markdown 语法中的 ``,实际上等同于 <code> 标签。实际作用是短代码块标签

而 markdown 语法中的长代码块就等同于 `<pre>` 标签,不同的博客或者网站的应用中还可以对 `<pre>` 加类名,用以展示不同的语言的语法高亮。

通过三者之间的对比可以看出,只有 <pre> 才是符合我们需求的。

确定好展示的方式后,就可以考虑进一步扩展格式化的功能。比如对象中还有属性是 JSON 字符串的话,咱也进一步的解析,直至最底层。想实现这种功能需要编写一个递归函数,考虑如下代码:

const isPlainObject = (v) => Object.prototype.toString.call(v) === "[object Object]"
const isString = (v) => Object.prototype.toString.call(v) === "[object String]"

/**
 * 格式 JSON 字符串为对象
 *
 * @author anran758
 * @param { any }
 */
function formatJsonStrAsObj(sample) {
  let temp = sample;

  if (isString(temp)) {
    // 因为有解析失败的可能,使用 try catch 做相应处理
    try {
      temp = JSON.parse(temp);
    } catch (ex) {
      // parse error,return this sample
      return sample;
    }
  }

  if (isPlainObject(temp)) {
    temp = { ...temp };

    Object.keys(temp).forEach(key => {
      const item = temp[key];

      // 字符串或者对象进行递归确认
      if (isString(item) || isPlainObject(item)) {
        temp[key] = formatJsonStrAsObj(item);
      }
    });
  }

  return temp;
}

/**
 * 将 JSON 字符串转换为带缩进的字符串
 *
 * @param {*} sample JSON 字符串
 * @param {number} [indnt=2] 缩进数
 * @returns
 */
function formatJSONIndnt(sample, indnt = 2) {
  const newSample = formatJsonStrAsObj(sample);

  if (isString(newSample)) return newSample;

  try {
    return JSON.stringify(newSample, null, indnt);
  } catch (ex) {
    return newSample.toString();
  }
}

const info = JSON.stringify({
  name: 'anran758',
  avatar: 'https://xxx',
  detail: JSON.stringify({
    desc: 'some description',
    level: 2,
  })
})
const data = formatJSONIndnt(info);
console.log(data);

// 可以直接将 data 输出至 dom


输入

上文讲了如何将数据输出至页面,以及扩展格式化功能的示例。接下来讲解输入方面的应用。

当用户从别的地方复制数据想粘贴至输入框时,可以在输入框上设置监控事件,触发事件后尝试帮用户格式化数据,示例代码如下:

<div class="container">
  <pre class="preview pre"></pre>
  <textarea class="textarea"></textarea>
</div>
const info = JSON.stringify({
  name: 'anran758',
  avatar: 'https://xxx',
  detail: JSON.stringify({
    desc: 'some description',
    level: 2,
  })
})
const data = formatJSONIndnt(info);

const textarea = document.querySelector('.textarea');
const preview = document.querySelector('.pre');

preview.innerHTML = data;
textarea.addEventListener('paste', (e) => {
  // 阻止默认事件
  e.preventDefault();
  const value = (e.clipboardData || window.clipboardData).getData('text');

  // 这里使用了上面定义的函数,进行格式化数据
  e.target.value = formatJSONIndnt(value, 2);
})
body {
  display: flex;
  margin: 0;
  justify-content: center;
  align-items: center;
  padding: 0 10px;
  box-sizing: border-box;
  min-height: 100vh;
}

.container {
  display: flex;
  width: 100%;
}

.preview {
  flex: 1;
  margin-bottom: 20px;
  padding: 20px;
  background: #f5fcff;
  border: 1px solid #d3eeff;
  border-radius: 3px;
  margin: 0;
}

.textarea {
  flex: 1;
  margin-left: 20px;
  padding: 10px;
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
    monospace;
}

.preview + .preview {
  margin-left: 10px;
}
原文 https://anran758.github.io/blog/2019/08/24/js-将JSON数据格式输出至页面上/

链接: https://fly63.com/article/detial/4943

双向数据绑定与单向数据绑定的各自优势和关系

在react中是单向数据绑定,而在vue和augular中的特色是双向数据绑定。为什么会选择两种不同的机制呢?我猜测是两种不同的机制有不同的适应场景,查了一些资料后,总结一下。

原生JS数据绑定的实现

双向数据绑定是非常重要的特性 —— 将JS模型与HTML视图对应,能减少模板编译时间同时提高用户体验。我们将学习在不使用框架的情况下,使用原生JS实现双向绑定 —— 一种为Object.observe

JavaScript判断数据类型的多种方法【 js判断一个变量的类型】

js判断数据类型的多种方法,主要包括:typeof、instanceof、 constructor、 prototype.toString.call()等,下面就逐一介绍它们的异同。

javascript中的typeof返回的数据类型_以及强制/隐式类型转换

由于js为弱类型语言拥有动态类型,这意味着相同的变量可用作不同的类型。 typeof 运算符返回一个用来表示表达式的数据类型的字符串,目前typeof返回的字符串有以下这些: undefined、boolean、string、number、object、function、“symbol

使用typeof obj===‘object’潜在的问题,并不能确定obj是否是一个对象?

在js中我们直接这样写typeof obj===‘object’有什么问题呢?发现Array, Object,null都被认为是一个对象了。如何解决这种情况,能保证判断obj是否为一个对象

js进制数之间以及和字符之间的转换

js要处理十六进制,十进制,字符之间的转换,发现有很多差不多且书写不正确的方法.一个一个实践才真正清楚如何转换,现在来记录一下它们之间转换的方法。

js判断数字是奇数还是偶数的2种方法实现

奇数和偶数的判断是数学运算中经常碰到的问题,这篇文章主要讲解通过JavaScript来实现奇偶数的判断。2种判断方法:求余% 、&1

js算法_判断数字是否为素数/质数

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。比如100以内共25个,js实现代码如下。

Js数据类型转换_JavaScript 那些不经意间发生的数据类型自动转换

JavaScript自动类型转换真的非常常见,常用的一些便捷的转类型的方式,都是依靠自动转换产生的。比如 转数字 : + x 、 x - 0 , 转字符串 : \\\"\\\" + x 等等。现在总算知道为什么可以这样便捷转换。

Js中实现XML和String相互转化

XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。 这篇文章主要介绍Js中实现XML和String相互转化

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!