118 lines
3.8 KiB
JavaScript
118 lines
3.8 KiB
JavaScript
/**
|
|
* 将JSON格式的HTML结构转换为HTML字符串
|
|
* @param {Object} json - JSON格式的HTML结构
|
|
* @returns {string} HTML字符串
|
|
*/
|
|
function jsonToHtml(json) {
|
|
if (!json || typeof json !== 'object') {
|
|
return '';
|
|
}
|
|
|
|
function parseElement(obj) {
|
|
if (obj === null || obj === undefined) {
|
|
return '';
|
|
}
|
|
|
|
if (typeof obj === 'string') {
|
|
return obj;
|
|
}
|
|
|
|
if (Array.isArray(obj)) {
|
|
return obj.map(item => parseElement(item)).join('');
|
|
}
|
|
|
|
// 检查是否为文本节点 (#text)
|
|
if ('#text' in obj) {
|
|
let tagName = 'div'; // 默认标签
|
|
let attributes = '';
|
|
let content = obj['#text'] || '';
|
|
|
|
// 处理属性和其他设置
|
|
for (const key in obj) {
|
|
if (key === '#text') continue;
|
|
|
|
if (key.startsWith('@')) {
|
|
// 属性 (@class, @id等)
|
|
const attrName = key.substring(1);
|
|
attributes += ` ${attrName}="${obj[key]}"`;
|
|
} else if (['div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'section', 'header', 'footer', 'main', 'article', 'aside'].includes(key)) {
|
|
// 子元素标签
|
|
tagName = key;
|
|
content = parseElement(obj[key]);
|
|
}
|
|
}
|
|
|
|
return `<${tagName}${attributes}>${content}</${tagName}>`;
|
|
}
|
|
|
|
// 普通元素节点
|
|
let tagName = 'div'; // 默认标签
|
|
let attributes = '';
|
|
let content = '';
|
|
|
|
for (const key in obj) {
|
|
if (key.startsWith('@')) {
|
|
// 属性 (@class, @id等)
|
|
const attrName = key.substring(1);
|
|
attributes += ` ${attrName}="${obj[key]}"`;
|
|
} else if (['div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'section', 'header', 'footer', 'main', 'article', 'aside', 'ul', 'ol', 'li', 'table', 'thead', 'tbody', 'tr', 'td', 'th'].includes(key)) {
|
|
// 明确指定的标签类型
|
|
tagName = key;
|
|
content = parseElement(obj[key]);
|
|
} else if (key === 'style') {
|
|
// style标签特殊处理
|
|
content += `<style>${obj[key]}</style>`;
|
|
} else if (key === 'title') {
|
|
// title标签特殊处理
|
|
content += `<title>${obj[key]}</title>`;
|
|
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
// 其他嵌套对象
|
|
content += parseElement(obj[key]);
|
|
} else if (key !== '#text') {
|
|
// 其他属性
|
|
attributes += ` ${key}="${obj[key]}"`;
|
|
}
|
|
}
|
|
|
|
return `<${tagName}${attributes}>${content}</${tagName}>`;
|
|
}
|
|
|
|
// 处理顶层html结构
|
|
if (json.html) {
|
|
const headContent = json.html.head ? parseElement(json.html.head) : '';
|
|
const bodyContent = json.html.body ? parseElement(json.html.body) : '';
|
|
const headSection = headContent ? `<head>${headContent}</head>` : '<head></head>';
|
|
const bodySection = bodyContent ? `<body>${bodyContent}</body>` : '<body></body>';
|
|
return `<!DOCTYPE html><html>${headSection}${bodySection}</html>`;
|
|
}
|
|
|
|
if (json.head || json.body) {
|
|
const headContent = json.head ? parseElement(json.head) : '';
|
|
const bodyContent = json.body ? parseElement(json.body) : '';
|
|
const headSection = headContent ? `<head>${headContent}</head>` : '<head></head>';
|
|
const bodySection = bodyContent ? `<body>${bodyContent}</body>` : '<body></body>';
|
|
return `<!DOCTYPE html><html>${headSection}${bodySection}</html>`;
|
|
}
|
|
|
|
return parseElement(json);
|
|
}
|
|
|
|
/**
|
|
* 生成随机字符串
|
|
* @param {number} length - 字符串长度
|
|
* @returns {string} 随机字符串
|
|
*/
|
|
function randomString(length) {
|
|
let result = '';
|
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
const charactersLength = characters.length;
|
|
for (let i = 0; i < length; i++) {
|
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export {
|
|
jsonToHtml,
|
|
randomString
|
|
}; |