前端面试题之将自定义数据结构转化成DOM元素
题目描述:
如下图所示:给你一个嵌套的dom数据结构,如何将它转化成jsx的dom元素;
输入:
const data = { tagName: 'ul', props: {'class': 'list'}, children: [ {tagName: 'li', children: ['douyin']},{tagName: 'li', children: ['toutiao']},{tagName: 'li', children: [{tagName: 'span',props: { 'class': 'span' },text: 'meituan'},]},]
};
输出:
<ul class="list"><li>douyin</li><li>toutiao</li><li><span>meituan</span></li>
</ul>
解题思路:
1.解读data数据结构,里面有tagName属性,我们可以使用document.createElement来创建html标签,并且复制给根元素element;
2.针对children属性,因为内部属性和父元素的属性是一样的,所以此处使用递归来调用函数即可
3.data数据显示文本有string、text属性两种格式;需要将这两种格式转化成节点类型的元素,方便使用appendChild将其放入到根元素element;
具体代码如下:
<script>/*** 将自定义数据结构转换为DOM元素* @param {Object} node - 包含标签名、属性和子节点的数据对象* @returns {HTMLElement} 生成的DOM元素*/function createDOMElement(node) {// 处理非对象类型(如文本节点)if (typeof node === 'string') {return document.createTextNode(node)}// 创建根元素elementconst element = document.createElement(node.tagName);// 设置元素属性if (node.props !== null && typeof node.props === 'object') {// 将node.props遍历,将其key, value通过setAttribute塞值给elementfor (let key in node.props) {element.setAttribute(key, node.props[key])}}// 处理子节点if (Array.isArray(node.children)) {// 递归处理子节点并添加到当前元素node.children.forEach(childNode => {const childElement = createDOMElement(childNode)// 将处理好的子节点push到elementelement.appendChild(childElement)})} else if (node.text) {// 处理文本节点element.appendChild(document.createTextNode(node.text))}return element}// 使用示例const data = {tagName: 'ul',props: { 'class': 'list' },children: [{ tagName: 'li', children: ['douyin'] },{ tagName: 'li', children: ['toutiao'] },{tagName: 'li',children: [{tagName: 'span',props: { 'class': 'span' },text: 'meituan'},]},]};// 生成DOM元素并插入到页面中const rootElement = createDOMElement(data);document.body.appendChild(rootElement);
</script>