You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mustache/Handlebars实现大JSON与HTML双向转换方案问询

JSON ↔ HTML 双向转换实现方案(含样式、图片渲染)

核心方案

  • 正向转换(JSON→HTML):用Handlebars模板引擎,直接在模板中嵌入CSS样式,通过JSON字段渲染图片,给每个元素加语义化类名(方便逆向解析)
  • 逆向转换(HTML→JSON):通过DOM选择器匹配类名,提取对应元素的文本、属性值,重新组装成原始JSON结构

1. 正向转换(JSON→HTML)实现

步骤1:定义JSON结构示例

假设你的JSON是产品类结构化数据(可根据实际结构调整):

{
  "pageTitle": "智能无线耳机详情",
  "product": {
    "name": "降噪无线耳机Pro",
    "description": "采用主动降噪技术,单次续航6小时,充电盒可提供18小时额外续航",
    "price": "399",
    "images": [
      {"url": "/assets/headphone-front.jpg", "alt": "耳机正面"},
      {"url": "/assets/headphone-side.jpg", "alt": "耳机侧面"}
    ],
    "specs": [
      {"key": "降噪模式", "value": "主动降噪/通透模式"},
      {"key": "连接方式", "value": "蓝牙5.3"},
      {"key": "防水等级", "value": "IPX4"}
    ]
  }
}

步骤2:编写Handlebars模板(含样式、类名)

直接在模板中嵌入CSS,给每个元素加唯一类名,方便后续逆向解析:

<script id="product-template" type="text/x-handlebars-template">
  <style>
    .product-container { max-width: 1200px; margin: 2rem auto; padding: 0 1rem; font-family: 'Segoe UI', sans-serif; }
    .product-header { border-bottom: 1px solid #eee; padding-bottom: 1rem; margin-bottom: 1.5rem; }
    .product-title { font-size: 1.8rem; color: #2d3748; margin: 0; }
    .product-desc { color: #4a5568; line-height: 1.6; margin: 1rem 0; }
    .product-price { font-size: 1.5rem; color: #e53e3e; font-weight: 600; }
    .product-images { display: flex; gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0; }
    .product-img { width: 200px; height: 200px; object-fit: cover; border-radius: 8px; }
    .product-specs { background: #f7fafc; padding: 1.5rem; border-radius: 8px; }
    .spec-item { display: flex; justify-content: space-between; padding: 0.5rem 0; border-bottom: 1px solid #edf2f7; }
    .spec-key { font-weight: 600; color: #2d3748; }
    .spec-value { color: #4a5568; }
  </style>
  <div class="product-container">
    <div class="product-header">
      <h1 class="product-title">{{pageTitle}}</h1>
      <p class="product-desc">{{product.description}}</p>
      <div class="product-price">¥{{product.price}}</div>
    </div>
    <div class="product-images">
      {{#each product.images}}
        <img src="{{url}}" alt="{{alt}}" class="product-img">
      {{/each}}
    </div>
    <div class="product-specs">
      {{#each product.specs}}
        <div class="spec-item">
          <span class="spec-key">{{key}}</span>
          <span class="spec-value">{{value}}</span>
        </div>
      {{/each}}
    </div>
  </div>
</script>

步骤3:JS代码实现转换

// 编译Handlebars模板
const templateSource = document.getElementById('product-template').innerHTML;
const renderTemplate = Handlebars.compile(templateSource);

// 加载JSON(实际项目中用fetch读取本地/远程文件)
const jsonData = { /* 上述JSON示例数据 */ };

// 生成HTML并插入页面
const htmlOutput = renderTemplate(jsonData);
document.getElementById('output').innerHTML = htmlOutput;

2. 逆向转换(HTML→JSON)实现

通过类名精准匹配元素,提取数据并组装成JSON:

function convertHtmlToJson() {
  const container = document.querySelector('.product-container');
  if (!container) return null;

  // 提取基础信息
  const pageTitle = container.querySelector('.product-title').textContent.trim();
  const desc = container.querySelector('.product-desc').textContent.trim();
  const price = container.querySelector('.product-price').textContent.replace('¥', '').trim();

  // 提取图片数据
  const images = Array.from(container.querySelectorAll('.product-img')).map(img => ({
    url: img.src,
    alt: img.alt.trim()
  }));

  // 提取规格数据
  const specs = Array.from(container.querySelectorAll('.spec-item')).map(item => ({
    key: item.querySelector('.spec-key').textContent.trim(),
    value: item.querySelector('.spec-value').textContent.trim()
  }));

  // 组装成原始JSON结构
  return {
    pageTitle,
    product: {
      name: pageTitle,
      description: desc,
      price,
      images,
      specs
    }
  };
}

// 使用示例:点击按钮导出JSON
document.getElementById('export-json').addEventListener('click', () => {
  const jsonResult = convertHtmlToJson();
  if (!jsonResult) return;

  // 下载JSON文件
  const blob = new Blob([JSON.stringify(jsonResult, null, 2)], { type: 'application/json' });
  const downloadLink = document.createElement('a');
  downloadLink.href = URL.createObjectURL(blob);
  downloadLink.download = 'product-data.json';
  downloadLink.click();
});

3. 解决Handlebars转换不符合预期的问题

  • 模板语法错误:检查循环({{#each}})、变量引用的路径是否和JSON结构匹配,比如product.images是否存在
  • 复杂逻辑处理:用Handlebars自定义助手函数处理条件判断、数据格式化,比如价格格式化:
Handlebars.registerHelper('formatPrice', (price) => `¥${parseFloat(price).toFixed(2)}`);
  • 调试技巧:用console.log打印JSON数据,确认字段是否存在;在模板中用{{log product}}输出变量内容

4. 批量处理JSON文件建议

如果需要批量转换本地JSON文件,用Node.js脚本实现(需先安装handlebars和fs-extra):

const fs = require('fs-extra');
const Handlebars = require('handlebars');

// 读取模板文件
const template = Handlebars.compile(fs.readFileSync('./product-template.hbs', 'utf8'));

// 遍历JSON目录
const jsonDir = './json-files';
const files = fs.readdirSync(jsonDir).filter(f => f.endsWith('.json'));

files.forEach(file => {
  const jsonData = fs.readJsonSync(`${jsonDir}/${file}`);
  const htmlContent = template(jsonData);
  // 生成对应HTML文件
  fs.writeFileSync(`./html-output/${file.replace('.json', '.html')}`, htmlContent);
});

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:43:16