You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何制作交互式textarea?或实现Chrome控制台式可展开数组展示方案

关于实现Chrome控制台式的可展开数组展示

嘿,我来帮你捋清楚这个问题!首先明确说:textarea完全做不到这种交互式的展开折叠效果。因为textarea是纯文本输入/输出控件,只能显示静态字符串——哪怕你用JSON.stringify(data, null, 2)格式化了输出,也只是带缩进的文本,没法响应点击事件、动态切换子元素的显示状态,更没法实现层级展开的交互逻辑。

那可行的替代方案有两种,根据你的需求复杂度选:

方案一:原生JS手动实现轻量版视图

适合不想引入额外库、需求简单的场景,核心思路是用递归把数组/对象转换成带交互的DOM结构:

步骤&示例代码

  1. 先准备HTML容器(替代textarea):
<div id="jsonViewer"></div>
  1. 加一点基础CSS样式,让结构更清晰:
/* 基础样式,可按需调整 */
#jsonViewer {
  font-family: Consolas, monospace;
  padding: 10px;
  background-color: #f5f5f5;
  border-radius: 4px;
}
.json-item {
  margin: 4px 0;
  padding-left: 16px;
}
.expand-btn {
  cursor: pointer;
  display: inline-block;
  width: 16px;
  text-align: center;
}
.hidden {
  display: none;
}
.json-type {
  color: #2c3e50;
  font-weight: bold;
}
  1. 写递归渲染的JS函数,处理数组和对象的层级展示:
function renderInteractiveJSON(data, container) {
  // 处理数组
  if (Array.isArray(data)) {
    // 数组头部:显示长度和折叠按钮
    const arrayHeader = document.createElement('div');
    arrayHeader.innerHTML = `
      <span class="expand-btn">▶️</span>
      <span class="json-type">Array(${data.length})</span>
    `;
    container.appendChild(arrayHeader);

    // 数组内容容器
    const arrayContent = document.createElement('div');
    arrayContent.classList.add('hidden');
    container.appendChild(arrayContent);

    // 点击切换展开/折叠
    arrayHeader.addEventListener('click', () => {
      arrayContent.classList.toggle('hidden');
      arrayHeader.querySelector('.expand-btn').textContent = arrayContent.classList.contains('hidden') ? '▶️' : '🔽';
    });

    // 遍历数组元素
    data.forEach((item, index) => {
      const itemHeader = document.createElement('div');
      itemHeader.innerHTML = `
        <span class="expand-btn">▶️</span>
        ${index}: {
      `;
      arrayContent.appendChild(itemHeader);

      const itemContent = document.createElement('div');
      itemContent.classList.add('hidden');
      arrayContent.appendChild(itemContent);

      itemHeader.addEventListener('click', () => {
        itemContent.classList.toggle('hidden');
        itemHeader.querySelector('.expand-btn').textContent = itemContent.classList.contains('hidden') ? '▶️' : '🔽';
      });

      // 渲染元素内容(递归调用)
      renderInteractiveJSON(item, itemContent);

      // 闭合括号
      const closingBracket = document.createElement('div');
      closingBracket.textContent = '}';
      arrayContent.appendChild(closingBracket);
    });
  } 
  // 处理对象
  else if (typeof data === 'object' && data !== null) {
    Object.keys(data).forEach(key => {
      const value = data[key];
      if (typeof value === 'object' && value !== null) {
        // 对象属性头部
        const propHeader = document.createElement('div');
        propHeader.innerHTML = `
          <span class="expand-btn">▶️</span>
          ${key}: {
        `;
        container.appendChild(propHeader);

        const propContent = document.createElement('div');
        propContent.classList.add('hidden');
        container.appendChild(propContent);

        propHeader.addEventListener('click', () => {
          propContent.classList.toggle('hidden');
          propHeader.querySelector('.expand-btn').textContent = propContent.classList.contains('hidden') ? '▶️' : '🔽';
        });

        // 递归渲染属性值
        renderInteractiveJSON(value, propContent);

        const closingBracket = document.createElement('div');
        closingBracket.textContent = '}';
        container.appendChild(closingBracket);
      } else {
        // 普通属性直接显示
        const propItem = document.createElement('div');
        propItem.textContent = `${key}: ${JSON.stringify(value)}`;
        container.appendChild(propItem);
      }
    });
  }
}

// 你的示例数据
const sampleData = [
  { "content": { "objectTypeID": "FGHD", "_id": "singlePro" } },
  { "content": { "objectTypeID": "KLM", "_id": "singlePro" } }
];

// 初始化渲染
const viewerContainer = document.getElementById('jsonViewer');
renderInteractiveJSON(sampleData, viewerContainer);

这段代码会生成和Chrome控制台类似的层级结构,点击箭头就能展开/折叠对应的层级。

方案二:用现成的第三方库

如果需要更完善的功能(比如语法高亮、编辑JSON、搜索等),直接用成熟的库更高效:

  • 如果你用React生态,推荐react-json-view,它开箱即用,支持展开折叠、语法高亮,还能编辑JSON内容
  • 纯原生JS环境可以用json-viewer-js这类轻量库,只需要引入库的JS和CSS文件,调用简单的API就能生成交互式视图

这类库都已经封装好了递归渲染、事件处理等逻辑,不用自己从头写。


内容的提问来源于stack exchange,提问作者Adam Jungen

火山引擎 最新活动