使用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
相关产品推荐
相关产品推荐

