作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有模板,我需要构建 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
是否是一个数组(在这种情况下,通过 tagBuilder
递归地 .map
它们,并且通过空字符串连接):
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));
如果您也需要在标签和 pretty-print 的 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
结构(我认为这是一个错误,因为它需要令人困惑的逻辑),那么提取标签、内容,以及数组中的 className,然后执行完全相同的操作:
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));
关于javascript - 如何在javaScript中从模板构建html?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60000000/
我是一名优秀的程序员,十分优秀!