javascript - 如何从javascript中的模板构建html?
问题描述
我有模板,我需要构建 html。我可以解析每个元素,但在尝试构建所有 html 时卡住了。我的代码暂时不起作用。并且可能我的方式是错误的,它应该是另一种从模板制作 html 的方法。任何人都可以帮忙吗?
const data = ['html', [
['head', [
['title', 'titletext'],
]],
['body', { class: 'bodyClass' }, [
['h1', { class: 'headerClass' }, 'h1text'],
['div', [
['span', 'span1text'],
['span', 'span2text'],
]],
]],
]];
const tagBuilder = (tagArray) => {
if (tagArray[1] instanceof Array) {
return tagBuilder(tagArray[1]);
}
if (tagArray[1] instanceof Object) {
return `<${tagArray[0]} class="${tagArray[1].class}">` + String(tagArray[2]) + `</${tagArray[0]}>`;
}
return `<${tagArray[0]}>` + String(tagArray[1]) + `</${tagArray[0]}>`;
}
const htmpBuilder = (data) => {
return data.map(element => tagBuilder(element));
};
document.getElementById("output").textContent = htmpBuilder(data);
<pre id="output">
</pre>
我需要的输出:
<html>
<head>
<title>titletext</title>
</head>
<body class="bodyClass">
<h1 class="headerClass">h1text</h1>
<div>
<span>span1text</span>
<span>span2text</span>
</div>
</body>
</html>
解决方案
您可能会考虑使用对象创建一个结构 - 这样,您只需查找.class
对象的属性,或对象的.contents
属性,或对象的.tag
属性,该过程可能会更有意义一眼。所涉及的唯一真正重要的逻辑是检查是否.contents
是一个数组(在这种情况下,递归.map
它们tagBuilder
并通过空字符串连接):
const data = {
tag: 'html',
contents: [
{
tag: 'head',
contents: [{
tag: 'title',
contents: 'titletext'
}]
}, {
tag: 'body',
class: 'bodyClass',
contents: [{
tag: 'h1',
class: 'headerClass',
contents: 'h1text'
}, {
tag: 'div',
contents: [{
tag: 'span',
contents: 'span1text'
}, {
tag: 'span',
contents: 'span2text'
}]
}]
}
]
};
const tagBuilder = ({ tag, class: className, contents = '' }) => {
const contentsStr = Array.isArray(contents)
? contents.map(tagBuilder).join('')
: contents;
return `<${tag}${className ? ` class="${className}"` : ''}>${contentsStr}</${tag}>`;
}
console.log(tagBuilder(data));
如果您也需要标签和漂亮打印的 HTML 之间的换行符(这通常无关紧要),那么indent
也传递一个参数,该参数被添加到标签行的开头(以及结束标签行的开头,当该标签包含非文本子项):
const data = {
tag: 'html',
contents: [
{
tag: 'head',
contents: [{
tag: 'title',
contents: 'titletext'
}]
}, {
tag: 'body',
class: 'bodyClass',
contents: [{
tag: 'h1',
class: 'headerClass',
contents: 'h1text'
}, {
tag: 'div',
contents: [{
tag: 'span',
contents: 'span1text'
}, {
tag: 'span',
contents: 'span2text'
}]
}]
}
]
};
const tagBuilder = ({ tag, class: className, contents = '' }, indent = 0) => {
const contentsStr = Array.isArray(contents)
? '\n' + contents.map(item => ' '.repeat(indent + 2) + tagBuilder(item, indent + 2)).join('\n') + '\n'
: contents;
return `<${tag}${className ? ` class="${className}"` : ''}>${contentsStr}${Array.isArray(contents) ? ' '.repeat(indent) : ''}</${tag}>`;
}
console.log(tagBuilder(data));
如果您必须使用原始data
结构(我认为这是一个错误,因为它需要混淆逻辑),然后从数组中提取标签、内容和类名,然后执行完全相同的操作:
const data = ['html', [
['head', [
['title', 'titletext'],
]],
['body', { class: 'bodyClass' }, [
['h1', { class: 'headerClass' }, 'h1text'],
['div', [
['span', 'span1text'],
['span', 'span2text'],
]],
]],
]];
const tagBuilder = (arr, indent = 0) => {
const tag = arr.shift();
const className = !Array.isArray(arr[0]) && typeof arr[0] === 'object'
? arr.shift().class
: '';
const contents = arr.length
? arr.shift()
: '';
const contentsStr = Array.isArray(contents)
? '\n' + contents.map(item => ' '.repeat(indent + 2) + tagBuilder(item, indent + 2)).join('\n') + '\n'
: contents;
return `<${tag}${className ? ` class="${className}"` : ''}>${contentsStr}${Array.isArray(contents) ? ' '.repeat(indent) : ''}</${tag}>`;
}
console.log(tagBuilder(data));
推荐阅读
- python - E: 找不到包 psql
- datadog - 用于活动 SFTP 连接的 datadog 中的最佳指标类型
- elasticsearch - 如何在 logstash 管道输出中格式化“cloud_auth”
- autohotkey - 如何消除 AutoHotKey 脚本中的尾随空格
- javascript - 里面的 ReactJS 代码{...}不渲染
- c++ - OpenCV imread(std::string filename, int flags) 在 c++ 中使用字符串文件名的变量时出现问题
- python - 并行处理捕获失败python
- java - 从 PySpark 运行 trainLDA 时面临 py4j 错误
- javascript - 为什么这个 SVG 动画被切成两半?
- youtube - 限制获取 Youtube 评论