2020-12-22 11:53:23 星期二

场景, HTML模板是多个div嵌套, 里边有列表, 也有键值对, 与之匹配的有一个json数据, 需要根据json去渲染这个HTML DOM

示例截图:

1. HTML模板

 1     <div id="test">
2 <div>{aa}</div>
3 <div>{bb}</div>
4 <div>{mm}</div>
5 <div>
6 <div class="cc">{n} : {v} : {mm}</div>
7 </div>
8 <div class="dd">
9 <div>{d1}</div>
10 <div>{d2}</div>
11 <div>{mm}</div>
12 <div class="d3">{x} : {y} : {mm}</div>
13 </div>
14 </div>

2. json数据 (注意mm, 这个键在内外层都有)

 1 {
2 'aa' : 'aa',
3 'bb' : 'bb',
4 'mm' : '1',
5 'cc' : [
6 {'n': 'n1', 'v' : 'v1', 'mm' : '2' },
7 {'n': 'n2', 'v' : 'v2', 'mm' : '2' },
8 {'n': 'n3', 'v' : 'v3', 'mm' : '2' },
9 ],
10 'dd' : [
11 'd1' : 'd1',
12 'd2' : 'd2',
13 'd3' : [
14 {'x' : 'x1', 'y': 'y1', 'mm': '4'},
15 {'x' : 'x2', 'y': 'y2', 'mm': '4'},
16 {'x' : 'x3', 'y': 'y3', 'mm': '4'},
17 ],
18 'mm' : '3'
19 ]
20 };

3. 渲染方法 (注意, 适用了递归, 先渲染内层的数据, 再渲染外层数据, 防止内外层有相同的键导致覆盖)

 1     /**
2 * @param node HTML DOM节点, 注意不是string
3 * @param arr json数组 注意是数组类型
4 * @return string 返回HTML字符串, 注意不是DOM节点
5 */
6 function repeatNode(node, arr) {
7
8 let out = [];
9 for (let i=0; i<arr.length; i++) {
10 let tmp = node.outerHTML;
11 console.log(tmp);
12 tmp = tmp.replace(/\s/g, ' '); //去掉回车换行, 减少空白符
13
14 let map = arr[i];
15 console.log(map);
16
17 //先渲染内层的数组
18 for (let j in map) {
19 if (map[j] instanceof Array) { //数组, 递归替换
20 let subNode = node.querySelector('.'+j);
21 let subHtml = repeatNode(subNode, map[j]); //递归
22 let subTpl = subNode.outerHTML.replace(/\s/g, ' ');
23 tmp = tmp.replace(subTpl, subHtml);
24
25 }
26 }
27
28 //再渲染内层的对象
29 for (let j in map) {
30
31 if (map[j] instanceof Object && !(map[j] instanceof Array)) { //对象, 递归替换
32
33 let subNode = node.querySelector('.'+j);
34 let subHtml = repeatNode(subNode, [map[j]]); //递归
35 let subTpl = subNode.outerHTML.replace(/\s/g, ' ')
36 tmp = tmp.replace(subTpl, subHtml);
37
38 }
39 }
40
41 //最后渲染外层的键值对/字符串
42 for (let j in map) {
43 if (typeof map[j] === 'string') { //字符串, 直接替换
44 let re = new RegExp('{' + j + '}', 'g');
45 tmp = tmp.replace(re, map[j]);
46
47 }
48 }
49
50 out.push(tmp);
51 }
52
53 return out.join('');
54 }

4. 全部代码

  1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=yes">
6 <title>Title</title>
7 <script src="/static/jquery.min.js"></script>
8 <style type="text/css">
9 div {margin:8px; margin-left: 10px; padding: 3px; border-radius: 5px; width: 80%;}
10 #test {background-color: #eee;}
11 .cc {background-color: #ccc;}
12 .dd {background-color: #aaa;}
13 .d3 {background-color: #888;}
14 </style>
15 </head>
16 <body>
17 <div id="target"></div>
18
19 <!-- 注意{mm}是内外层都有 -->
20 <template id="tpl">
21 <div id="test">
22 <div>{aa}</div>
23 <div>{bb}</div>
24 <div>{mm}</div>
25 <div>
26 <div class="cc">{n} : {v} : {mm}</div>
27 </div>
28 <div class="dd">
29 <div>{d1}</div>
30 <div>{d2}</div>
31 <div>{mm}</div>
32 <div class="d3">{x} : {y} : {mm}</div>
33 </div>
34 </div>
35 </template>
36
37 <script type="text/javascript">
38 let arr = [{"aa":"aa","bb":"bb","mm":"1","cc":[{"n":"n1","v":"v1","mm":"2"},{"n":"n2","v":"v2","mm":"2"},{"n":"n3","v":"v3","mm":"2"}],"dd":{"d1":"d1","d2":"d2","d3":[{"x":"x1","y":"y1","mm":"4"},{"x":"x2","y":"y2","mm":"4"},{"x":"x3","y":"y3","mm":"4"}],"mm":"3"}}];
39
40 let tpl = document.getElementById('tpl').innerHTML;
41 let node = htmlToNode(tpl);
42 //console.log(node);
43
44 document.getElementById('target').innerHTML = repeatNode(node, arr);
45
46 /**
47 * @param node HTML DOM节点, 注意不是string
48 * @param arr json数组 注意是数组类型
49 * @return string 返回HTML字符串, 注意不是DOM节点
50 */
51 function repeatNode(node, arr) {
52
53 let out = [];
54 for (let i=0; i<arr.length; i++) {
55 let tmp = node.outerHTML;
56 console.log(tmp);
57 tmp = tmp.replace(/\s/g, ' '); //去掉回车换行, 减少空白符
58
59 let map = arr[i];
60 console.log(map);
61
62 //先渲染内层的数组
63 for (let j in map) {
64 if (map[j] instanceof Array) { //数组, 递归替换
65 let subNode = node.querySelector('.'+j);
66 let subHtml = repeatNode(subNode, map[j]); //递归
67 let subTpl = subNode.outerHTML.replace(/\s/g, ' ');
68 tmp = tmp.replace(subTpl, subHtml);
69
70 }
71 }
72
73 //再渲染内层的对象
74 for (let j in map) {
75
76 if (map[j] instanceof Object && !(map[j] instanceof Array)) { //对象, 递归替换
77
78 let subNode = node.querySelector('.'+j);
79 let subHtml = repeatNode(subNode, [map[j]]); //递归
80 let subTpl = subNode.outerHTML.replace(/\s/g, ' ')
81 tmp = tmp.replace(subTpl, subHtml);
82
83 }
84 }
85
86 //最后渲染外层的键值对/字符串
87 for (let j in map) {
88 if (typeof map[j] === 'string') { //字符串, 直接替换
89 let re = new RegExp('{' + j + '}', 'g');
90 tmp = tmp.replace(re, map[j]);
91
92 }
93 }
94
95 out.push(tmp);
96 }
97
98 return out.join('');
99 }
100
101 function htmlToNode(html) {
102 let div = document.createElement('div');
103 let pos = html.indexOf('<'); //避免开头有空白
104 div.innerHTML = html.substring(pos);
105 return div.firstChild;
106 }
107
108
109 </script>
110
111 </body>
112 </html>

推荐几个自己开发的小工具:

SummerPHP一款简洁的PHP框架, 支持多种方式渲染HTML, 支持接口化

zbJSTool好用的js库集合, 单页面路由框架, 前端生成分享图等等

microStore 单页面, 小巧, 适用移动端的个人商店系统

根据json数据和HTML模板,渲染嵌套的HTML的更多相关文章

  1. 使用jQuery解析JSON数据

    我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. 上例中得到的JSON数据如下,是一个嵌套JSON: {"comments&quo ...

  2. 使用jQuery解析JSON数据(由ajax发送请求到php文件处理数据返回json数据,然后解析json写入html中呈现)

    在上一篇的Struts2之ajax初析中,我们得到了comments对象的JSON数据,在本篇中,我们将使用jQuery进行数据解析. 我们先以解析上例中的comments对象的JSON数据为例,然后 ...

  3. JQuery- 解析JSON数据

    我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法.上例中得到的JSON数据如下,是一个嵌套JSON: {,,"nickname&qu ...

  4. 深入分析jquery解析json数据

    我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. JSON数据如下,是一个嵌套JSON: {"comments":[{& ...

  5. 使用jQuery解析JSON数据-已验证

    本文来源于:http://www.cnblogs.com/codeplus/archive/2011/07/18/2109544.html 上例中得到的JSON数据如下,是一个嵌套JSON: {&qu ...

  6. Ajax接收Json数据,调用template模板循环渲染页面的方法

    一. 后台接口吐出JSON数据 后台php接口中,需要写三个部分: 1.1 开头header规定数据格式: header("content-type:application/json;cha ...

  7. 移动端基于HTML模板和JSON数据的JavaScript交互

    写本文之前,我正在做一个基于Tab页的订单中心: 每点击一个TAB标签,会请求对应状态的订单列表.之前的项目,我会在js里使用 +  连接符连接多个html内容: var html = ''; htm ...

  8. ASP.NET提取多层嵌套json数据的方法

    本文实例讲述了ASP.NET利用第三方类库Newtonsoft.Json提取多层嵌套json数据的方法,具体例子如下. 假设需要提取的json字符串如下: {"name":&quo ...

  9. HTML和JSON的数据交互-HTML模板

    直接上源码,原文http://www.zhangxinxu.com/wordpress/2012/09/javascript-html-json-template/ <!DOCTYPE html ...

随机推荐

  1. Kafka作为分布式消息系统的系统解析

    Kafka概述 Apache Kafka由Scala和Java编写,基于生产者和消费者模型作为开源的分布式发布订阅消息系统.它提供了类似于JMS的特性,但设计上又有很大区别,它不是JMS规范的实现,如 ...

  2. 推荐:国产etl调度工具Taskctl web应用版,0元永久授权

    写在前面 2020年疫情席卷全球,更是对整个市场经济造成了严重影响,年初疫情肆虐,西方世界单方面的科技.经济封锁,国际关系吃紧.....导致很多中小型企业业务链受阻,大型企业经费资金吃紧,轮班制导致公 ...

  3. 使用github actions 完成一些自动化工作

    github actions 是什么? github actions是github的持续集成及自动化工作流服务,使用起来都比较方便.大部分github actions都可以在https://githu ...

  4. 6.2 Binding基础

    WPF最为核心的思想是数据驱动UI,实现这一技术的基石就是绑定技术(binding).如果把Binding比作数据的桥梁,那么它的两端分别是源(Source)和目标(Target),Binging是架 ...

  5. fist-第三天冲刺随笔

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  6. Fist—— 团队展示

    作业要求 软件工程1班 团队名称 Fist 这个作业的目标 团队合作开发项目,加强团队合作,进一步了解相应岗位. 作业正文 https://www.cnblogs.com/team4/p/137730 ...

  7. 学习abp vnext框架到精简到我的Vop框架

    学习目标 框架特点 基于.NET 5平台开发 模块化系统 极少依赖 极易扩展 ....... 框架目的 学习.NET 5平台 学习abp vnext 上图大部分功能已经实现,多数是参考(copy)ab ...

  8. opencv-python imread、imshow浏览目录下的图片文件

    ☞ ░ 前往老猿Python博文目录 ░ 一.几个知识点 1.1.使用Python查找目录下的文件 具体请参考<Python正则表达式re模块和os模块实现文件搜索模式匹配>. 1.2.o ...

  9. Python函数独立星号(*)分隔的命名关键字参数

    如果需要限制关键字参数的输入名字,就需要使用到命名关键字参数的形式,所谓命名关键字参数就是给关键字参数限定指定的名字,输入其他名字不能识别.命名关键字参数和位置参数之间使用独立的星号(*)分隔,星号后 ...

  10. 【软件测试部署基础】yarn的认识

    1. yarn是什么 Yarn 是 Facebook, Google, Exponent 和 Tilde 开发的一款新的 JavaScript 包管理工具.其主要是为了弥补 npm 的一些少量的缺陷而 ...