json
- 它是一个对象,是为了数据传输,为了前后端的通讯
属性名强制加双引号
{
"name": "Tracy",
"age" : 18
} - JSON 是一个静态类,相当于 Match, 有各种方法可以使用
- 前端传 json 给后端
var obj = { "name" : "Tracy", "age" : 18};
JSON.stringfy(obj); //把对象转换成 字符串的 json 格式,传输给后台 - 后端传 json 给前端
var str = JSON.stringfy(obj); //后端传过来的 也是字符串的 json 格式
var obj = JSON.parse(str);// 把 json 行形式的字符串转换为对象
- 前端传 json 给后端
异步加载
- 在页面加载的时候,html 和 css 是并行一起被解析的,在解析的时候分别生成 domTree 和 cssTree 它们加合并在一起汇成了一个 renderTree (渲染树) 然后再汇成一个页面 我们把 JS 写在下边,就相当于在生成 domTree 的时候页面刚刚解析完(而不是下载完)的时候就执行 JS
比如说 image, 图片 size 很大,解析完的意思是: 认出了这个是一个 image 标签后然后马上挂到树上去,而开启另一个新的线程,异步同时下载这个图片。 - domTree 遵循深度优先原则,既 先遍历 html 然后遍历 head 和里面的所有 meta, 都遍历结束后,再遍历 body 里的标签
- 我们要尽量减少 js 对于节点的添加和删除操作,如果必须要做,也要尽量一次性做完,因为一旦 节点变了,相当于 domTree 变了,进而 randerTree 也变了,然后页面需要重新绘制一遍,影响页面效率。
以下情况会导致页面 randerTree 的 reflow 重排- dom 节点的删除,添加
- dom 节点的宽高变化,位置变化(display:none/block)
因为一个元素的高度变了,页面其他元素的相应都会发生改变 - 查看 dom 节点的位置 offsetWidth, offsetLeft,
为何它要重绘页面? 因为调用的时候页面重排这样返回的值才是时时的
- repaint 重绘, 这个也会稍微影响页面效率, 不过是可以忍受的,它不会把整个页面都重绘,只是一部分。
- 改变 dom 节点的颜色
- 改变 dom 节点的背景图片
-
普通加载 js
- 一些 js, 并不改变页面,就是一些工具包的 js, 我们需要做异步加载,这样一边下载 js 一边下载 html css 互相不受影响, 否则页面会在执行到 js 的时候空白,如果下载不了这个 js 页面会一直持续空白
JS 加载的缺点: 加载工具方法没有必要阻塞文档,过多加载 js 会影响页面效率,一旦网速不好,那么整个网页将等待 js 加载而不进行后续渲染等工作 - 有些工具方法需要按需加载,需要调用的时候加载,不需要调用的时候就不加载
- 普通 js 下载完立即执行
- 一些 js, 并不改变页面,就是一些工具包的 js, 我们需要做异步加载,这样一边下载 js 一边下载 html css 互相不受影响, 否则页面会在执行到 js 的时候空白,如果下载不了这个 js 页面会一直持续空白
-
异步加载 js 三种方案
- defer 异步加载,但要等 dom 文档全部解析完才会被执行(既: domTree 生成完毕)。 只有 IE 能用,也可以将代码写到内部
(Tips: 凡是属性名等于属性值的,我们只写属性名就行了,比如这里的 defer 其实是 defer="defer" 的简写)
<script defer src="#.js"></script>
<script defer ></script> some js code ... <script> - async 异步加载,加载完就执行, async 只能加载外部脚本,不能把 js 写在 script 标签里, W3C 标准方法, IE9 以上浏览器都能用
<script async src="#.js"></script> - 如何让上面两个兼容呢? 这里就提出的最常用的第三种方法:
创建 script, 插入到 dom 中,加载完毕后 callBack
它除了可以实现异步加载,也可以实现按需加载
比如说一个用户点击一个按钮之后,才下载一个 tool.js 然后执行里面的某个函数<script> var scrpit = document.createElement('script'); scrpit.type = "text/javascript"; scrpit.src = "tool.js";//这个分号执行完,系统就发了一个请求异步下载这个文件了 if(scrpit.readyState){ //只有 IE 有的方法 scrpit.onreadystatechange = function(){ if(scrpit.readyState == "complete" || scrpit.readyState == "loaded") { text(); } } }else{ scrpit.onload = function(){ //但是 IE 没有这个方法 //这里就是说 script 下载完了之后开始执行的code text(); //假设 tool.js 里有这个 text(); 方法,如果不写到这里的话,我们马上直接调用的话,会报错,因为 js 文件还没有下载完毕 } } document.head.appendChild(scrpit);//这句话写出来,就开始执行 js 了,这句话不写就永远不执行 </script> 上面的 code 打包成一个函数 The best way to load external JavaScript function loadScript(url, callback){ var script = document.createElement("script") script.type = "text/javascript"; if(callback){ if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); } loadScript('tool.js', function(){ text();}); //调用js 并且执行里面的方法 loadScript('tool.js'); //只调用 js
- defer 异步加载,但要等 dom 文档全部解析完才会被执行(既: domTree 生成完毕)。 只有 IE 能用,也可以将代码写到内部
浏览器加载时间线
- 创建 Document 对象,开始解析 web 页面。解析HTML元素和他们的文本内容后添加 Element 对象和 Text 节点到文档中。这个阶段document.readyState = ‘loading’。
- 遇到 link 外部 css,创建线程进行异步加载,并继续解析文档。
-
- 遇到 script 外部 js,并且没有设置 async、defer,浏览器加载,并阻塞,等待 js 加载完成并执行该脚本,然后继续解析文档。
- 遇到script外部js,并且设置有async、defer,浏览器创建线程异步加载,并继续解析文档。 对于async属性的脚本,脚本加载完成后立即执行。(异步加载的 js 禁止使用document.write() 方法,它会把所有页面的东西覆盖,相当于 window.onload = function(){document.write("a");})
- 遇到img等带 src 的标签,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档。
- 当文档解析完成后 (domeTree 构建完,解析完不代表加载完,所有文件都下载完)
- document.readyState = ‘interactive’。
- 所有设置有defer的脚本会按照顺序执行。(注意与async的不同,但同样禁止使用document.write());
- document 对象触发 DOMContentLoaded 事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。 (这个事件只在 addEventLisener 上有用,不能直接写 .onDOM.... ,这个方法就是 dome 解析完直接可以执行的函数,就比 window.onload 强了很多)
document.addEventListener('DOMContentLoaded',function(){...js 写法... },false); == $(document).ready(function(){ ... 这个是jQuery 写法...})
- 当所有 async 的脚本加载完成并执行后、img 等加载完成后,document.readyState = ‘complete’,window对象触发load事件。
- 从此,以异步响应方式处理用户输入、网络事件等。