json 介绍
后台 -> 提供一个数据请求的接口, 前端通过接口地址可以请求到后台的数据
前端 -> 前端得到数据后, 需要进行数据解析, 把数据绑定在 html 页面上 -> "数据绑定"
sequenceDiagram
前端 ->> 后台: 发送请求获取数据
后台 ->> 前端: 把准备好的数据返回给前端
后台 -->> 前端: (后台给前端返回的数据一般都是 json 格式的)
上面是 markdown 的流程图语法, 但是简书好像不支持, 只有截图了 (下图)
前后端交互
json 不是一个单独的数据类型, 它只是一种特殊的数据格式 -> 它是对象数据类型的
- var obj = {name:"lilei", age: 18}; // 普通格式对象
- var jsonObl = {"name":"lilei","age":17}; // json 格式对象
- // 相对于普通的格式来说, 只是把属性名用双引号包起来了 (只能是双引号)
在 window 浏览器对象中, 提供了一个叫 json 的属性, 它这里面提供了两个方法:
JSON.parse -> 把 JSON 格式的字符串转换为 JSON 格式的对象
JSON.stringify -> 把 JSON 格式的对象转换为 JSON 格式的字符串
- var jsonObj = {"name":"lilei","age":17};
- var jsonStr = JSON.stringify(jsonObj);
- console.log(jsonStr) // '{"name":"lilei","age":17}'
- console.log(JSON.parse(jsonStr))// {name: "lilei", age: 17}
在 ie6~7 浏览器中, 我们的 window 下没有 JSON 对象, 刚才的 parse 和 stringify 都不存在了
- // 把 JSON 格式的对象转换为 JSON 格式的字符串
- var str = '{"name":"lilei","age":17}';
- JSON.parse(str);
- eval("(" + str + ")"); // 使用 eval, 不要忘记手动的加一个小括号
json 数据绑定
- json.html
- <style type="text/CSS">
- *{
- padding: 0;
- margin: 0;
- }
- li{
- list-style: none;
- }
- #ul1{
- width: 150px;
- margin: 30px auto;
- padding: 12px;
- border: 1px solid green;
- }
- #ul1 li{
- /* 超出文本的自动裁切 */
- text-overflow: ellipsis; /* 超出文本的以 ... 显示 */
- white-space: nowrap; /* 强制不换行 */
- overflow: hidden; /* 溢出隐藏 */
- }
- #ul1 li span{
- display: inline-block;
- width: 28px;
- height: 28px;
- background: red;
- border-radius: 50%;
- line-height: 28px;
- text-align: center;
- color: #fff;
- margin: 12px 10px 0 0;
- }
- </style>
- <ul id="ul1">
- <li><span class="bg">01</span>aaaaaaaaaaaaa</li>
- <li><span class="bg">02</span>bbbbbbbbbbbbb</li>
- <li><span class="bg">03</span>ccccccccccccc</li>
- </ul>
- <script type="text/javascript" src="json.js"></script>
- json.js
- var jsonObj = [
- {
- "title":"qqqqqqqqqqqqqq",
- "desc":"q1q1q1q1q1q1q1q1q1q1q1"
- },
- {
- "title":"wwwwwwwwwwwwww",
- "desc":"w2w2w2w2w2w2w2w2w2w2w2"
- },
- {
- "title":"eeeeeeeeeeeeee",
- "desc":"e1e1e1e1e1e1e1e1e1e1e1"
- },
- {
- "title":"rrrrrrrrrrrrrr",
- "desc":"r1r1r1r1r1r1r1r1r1r1r1"
- },
- {
- "title":"tttttttttttttt",
- "desc":"t1t1t1t1t1t1t1t1t1t1t1"
- },
- {
- "title":"yyyyyyyyyyyyyy",
- "desc":"y1y1y1y1y1y1y1y1y1y1y1"
- },
- {
- "title":"uuuuuuuuuuuuuu",
- "desc":"u1u1u1u1u1u1u1u1u1u1u1"
- },
- {
- "title":"iiiiiiiiiiiiii",
- "desc":"i1i1i1i1i1i1i1i1i1i1i1"
- }
- ]
- var oUl = document.getElementById("ul1");
- var oLis = oUl.getElementsByTagName("li");
- // 鼠标移入移出, 背景变色
- for (var i = 0; i <oLis.length; i++) {
- oLis[i].onmouseover = function (){
- this.style.backgroundColor = 'pink';
- }
- oLis[i].onmouseout = function (){
- this.style.backgroundColor = '';
- }
- }
利用动态创建元素节点和把它追加到页面中的方式来实现数据绑定
优势: 把需要动态绑定的内容一个个追加到页面中, 对原来的元素没有任何影响
弊端: 浏览器每创建一个 li, 就添加到页面中, 引发一次 DOM 回流, 最后引发会留的次数过多, 影响我们的性能
- for (var i = 0; i < jsonObj.length; i++) {
- var cur = jsonObj[i];
- var oLi = document.createElement("li");
- var num = i+4
- if(num<10){
- num = "0" + num
- }
- oLi.innerHTML = "<span>" + num + "</span>" + cur.title;
- oUl.appendChild(oLi)
- }
字符串拼接的方式: 首先循环需要绑定的数据, 然后把需要动态绑定的标签以字符串的方式拼接到一起, 拼接完成后, 最后统一添加到页面中 ("字符串拼接绑定数据是工作中最常用的一种绑定数据的方式" -> 模板引擎数据绑定 )
优势: 事先把内容拼接好, 最后添加到页面中, 只引发一次回流
弊端: 把新拼接的字符串添加到 #ul1 中, 原有的三个 li 的鼠标滑过效果都消失了 (原来标签绑定的时间都消失了)
- var str = "";
- for (var i = 0; i <jsonObj.length; i++) {
- var cur = jsonObj[i];
- var num = i+4
- if(num<10){
- num = "0" + num
- }
- str += "<li>";
- str += "<span>" + num + "</span>";
- str += cur.title;
- str += "</li>"
- }
- // console.log(str);
- oUl.innerHTML += str; // -> oUl.innerHTML = oUl.innerHTML + str;
- // (把之前的三个 li 以字符串的方式获取到)+str ;
- // (拼接完成的整体还是字符串, 最后再把字符串统一的添加到页面中, 浏览器还需要把字符串渲染成对应的标签)
文档碎片
- var frg = document.createDocumentFragment();
- // 创建一个文档碎片, 相当于临时创建一个容器
- for (var i = 0; i <jsonObj.length; i++) {
- var cur = jsonObj[i];
- var oLi = document.createElement("li");
- var num = i+4
- if(num<10){
- num = "0" + num
- }
- oLi.innerHTML = "<span>" + num + "</span>" + cur.title;
- frg.appendChild(oLi)
- }
- oUl.appendChild(frg)
- frg = null;
js 中 DOM 深入知识:
-> 回流 (重排 reflow): 当页面中的结构发生改变 (增加 / 删除元素, 位置发生改变...), 浏览器都需要重新的计算一遍最新的 DOM 结构, 重新的进行渲染
-> 重绘: 某一个元素的部分样式发生改变了, 浏览器只需要重新的渲染当前元素即可
来源: http://www.jianshu.com/p/52dcf1fe168f