根据json数据和HTML模板,渲染嵌套的HTML
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的更多相关文章
- 使用jQuery解析JSON数据
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. 上例中得到的JSON数据如下,是一个嵌套JSON: {"comments&quo ...
- 使用jQuery解析JSON数据(由ajax发送请求到php文件处理数据返回json数据,然后解析json写入html中呈现)
在上一篇的Struts2之ajax初析中,我们得到了comments对象的JSON数据,在本篇中,我们将使用jQuery进行数据解析. 我们先以解析上例中的comments对象的JSON数据为例,然后 ...
- JQuery- 解析JSON数据
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法.上例中得到的JSON数据如下,是一个嵌套JSON: {,,"nickname&qu ...
- 深入分析jquery解析json数据
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. JSON数据如下,是一个嵌套JSON: {"comments":[{& ...
- 使用jQuery解析JSON数据-已验证
本文来源于:http://www.cnblogs.com/codeplus/archive/2011/07/18/2109544.html 上例中得到的JSON数据如下,是一个嵌套JSON: {&qu ...
- Ajax接收Json数据,调用template模板循环渲染页面的方法
一. 后台接口吐出JSON数据 后台php接口中,需要写三个部分: 1.1 开头header规定数据格式: header("content-type:application/json;cha ...
- 移动端基于HTML模板和JSON数据的JavaScript交互
写本文之前,我正在做一个基于Tab页的订单中心: 每点击一个TAB标签,会请求对应状态的订单列表.之前的项目,我会在js里使用 + 连接符连接多个html内容: var html = ''; htm ...
- ASP.NET提取多层嵌套json数据的方法
本文实例讲述了ASP.NET利用第三方类库Newtonsoft.Json提取多层嵌套json数据的方法,具体例子如下. 假设需要提取的json字符串如下: {"name":&quo ...
- HTML和JSON的数据交互-HTML模板
直接上源码,原文http://www.zhangxinxu.com/wordpress/2012/09/javascript-html-json-template/ <!DOCTYPE html ...
随机推荐
- 追踪聚光特效怎么实现,有Vegas就够了
舞台聚光灯大家一定都不陌生,在电视上某些颁奖活动里,主持人的进场一定伴随着舞台灯光的聚光效果.随着主持人的移动,灯光也随之移动.这里的舞台灯光就起到了一个追踪聚光的效果. Vegas Pro 16 增 ...
- QQ账号测试用例
- python基础之操作列表
遍历元素 magicians = ['alice','david','carolina'] for magician in magicians: print(magician) magicians = ...
- C语言讲义——结构化编程(分支、循环)
顺序结构(从上到下) 分支结构(也叫选择结构) 循环结构 分支结构 if...else 最基本的分支结构是if(){}else{}. 为了代码的安全,同时也是出于代码规范的考虑,if()后面一定要加花 ...
- Java蓝桥杯——贪心算法
贪心算法 贪心算法:只顾眼前的苟且. 即在对问题求解时,总是做出在当前看来是最好的选择 如买苹果,专挑最大的买. 最优装载问题--加勒比海盗 货物重量:Wi={4,10,7,11,3,5,14,2} ...
- 通过Consul Raft库打造自己的分布式系统
通用的CP系统有etcd和consul, 通用的对立面就是专用系统. 所以在某些场合是有这种需求的. 然而etcd embed的可用性极差, Windows上面跑会出现各种问题, 而且不能定制协议, ...
- Pytest自动化测试 - allure报告进阶
Allure除了具有Pytest基本状态外,其他几乎所有功能也都支持. 1.严重性 如果你想对测试用例进行严重等级划分,可以使用 @allure.severity 装饰器,它可以应用于函数,方法或整个 ...
- Calendar类、 System类、 StringBulider类、 包装类
Calendar类 概念 java . util . Calendar 日历类,抽象类,在Date类后出现的,替换掉了很多Date类中的方法.该类将所有的可能用到的时间信息封装为静态成员变量. ...
- 测试开发工程必备技能之一:Mock的使用
1. 背景 在实际产品开发过程中,某个服务或前端依赖一个服务接口,该接口可能依赖多个底层服务或模块,或第三方接口,比如说服务 A 依赖服务B,服务B又依赖服务 C,如下图所示: 这种依赖的问题会导致原 ...
- Spring Cloud Alibaba 初体验(三) Nacos 与 Dubbo 集成
一.新建项目 新建项目,只放置接口,用于暴露 Dubbo 服务接口 public interface GreetingService { String greeting(); } 二.provider ...