JS-WEB-API
常說的JS(瀏覽器執行的JS)包含兩部分:
- JS基礎知識:ECMA 262標准
- JS-WEB-API:W3C標准
W3C標准中關於JS的規定有:
- DOM操作
- BOM操作
- 事件綁定
- Ajax請求(包括HTTP協議)
- 存儲
例如:頁面彈窗是 window.alert(123),瀏覽器需要做:
- 定義一個 window 全局變量,對象類型
- 給它定義一個 alert 屬性,屬性值是一個函數
獲取元素 document.geiElementById(id),瀏覽器需要:
- 定義一個 document 全局變量,對象類型
- 給它定義一個 geiElementById 屬性,屬性值是一個函數
Document Object Model (DOM)
- DOM是哪種基本的數據解構? 樹形結構的文檔對象模型
- DOM操作常用API有哪些?
- DOM 節點的attr 和 propery 有何區別?
一、DOM節點操作
1、獲取
var a = document.getElementById("div1"); var b = document.getElementsByTagName('div'); var c = document.getElementsByClassName('.container'); var d = document.querySelectorAll('p');
2、property
修改的是JS對象的標准屬性
3、attribute
修改獲取的是HTML文檔中標簽的屬性
DOM結構操作
新增節點,添加節點
var div1 = document.getElementById('div1'); //添加新節點 var p1 = document.createElement("p"); p1.innerHTML = 'this is p1'; div1.appendChild(p1); //添加創建的新元素 //移動已有節點 var p2 = document.getElementById("p2"); div1.appendChild(p2);
獲取父元素與子元素、移除節點
var div1 = document.getElementById("div1"); var parent = div1.parentElement; var child = div1.childNodes; //移除節點 div1.removeChild(child[0]);
二、BOM操作(Browser Object Model)
- 檢測瀏覽器類型
- 拆解 url 各部分
知識點
- navigator & screen
-
//檢測瀏覽器類型
var ua = navigator.userAgent; var isChrome = ua.indexOf('Chrome'); console.log(isChrome); //screen 獲取屏幕大小 console.log(screen.width); console.log(screen.height);loaction & history
-
//拆解URL各部分
//loaction console.log(location.href); //當前域名
console.log(location.host); //當前域名
console.log(location.protocol); //協議 http: console.log(location.pathname); //當前分目錄名 console.log(location.search); // 查詢部分:‘?’之后部分 console.log(location.hash); //‘#’ 后面的字符 //history history.back(); history.forward();
三、事件
- 編寫一個通用的事件監聽函數
- 描述事件冒泡流程
- 對於一個無限下拉加載圖片的頁面,如何給每個圖片綁定事件
通用事件綁定
var btn = document.getElementById('btn1'); btn.addEventListener('click',function(event){ console.log('clicked'); }); function bindEvent(elem,type,fn){ elem.addEventListener(type,fn); } var a = document.getElementById('link1'); bindEvent(a,'click',function(e){ e.preventDefault(); alert('clicked'); })
IE低版本使用 attachEvent 綁定事件,和 w3c 標准不一樣
事件冒泡
按照DOM樹形結構,由子級到祖級的順序傳播
案例:點擊p1彈出激活,點擊其他的彈出取消
<div id="div1"> <p id="p1">激活</p> <p id="p2">取消</p> <p id="p3">取消</p> <p id="p4">取消</p> </div> <div id="div2"> <p id="p5">取消</p> <p id="p6">取消</p> </div> <script type="text/javascript"> var p1 = document.getElementById('p1'); var body = document.body; function bindEvent(elem,type,fn){ elem.addEventListener(type,fn); } bindEvent(p1,'click',function(e){ e.stopPropagation(); alert('激活'); }) bindEvent(body,'click',function(){ alert('取消'); })
事件代理
事件代理就是在祖級DOM元素綁定一個事件,當觸發子孫級DOM元素的事件時,利用事件流的原理來觸發綁定在祖級DOM的事件。
<div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <a href="#">a3</a> <a href="#">a4</a> <!-- 會隨時新增更多的 a 標簽 --> </div> <script type="text/javascript"> var div1 = document.getElementById('div1'); div1.addEventListener('click',function(e){ //target屬性返回觸發該事件的節點 var target = e.target; //nodeName返回的標簽名都是大寫 if(target.nodeName == 'A'){ alert(target.innerHTML); } }) </script>
完善通用綁定事件函數
function bindEvent(elem,type,selector,fn){ if(fn == null){ fn = selector; selector = null; } elem.addEventListener(type,function(e){ var target;
//使用代理 if (selector){ target = e.target;
//如果target是指定的選擇器 if(target.matches(selector)){
//讓target使用fn的方法,修改this的指向 fn.call(target,e); }
//不使用代理 }else{ fn(e); } }) } //使用代理 var div1 = document.getElementById('div1'); bindEvent(div1,'click','a',function(e){ console.log(this.innerHTML); }) //不使用代理 var a = document.getElementById('a'); bindEvent(div1,'click',function(e){ console.log(a.innerHTML); })
代理的好處
- 代碼簡潔
- 減少瀏覽器內存占用(因為綁一次事件瀏覽器會計一次)
四、Ajax
- 手動編寫一個 ajax,不依賴第三方庫
- 跨域的幾種實現方式
XMLHttpReaquest
var xhr = new XMLHttpRequest(); xhr.open("GET","/api",false); xhr.onreadystatechange = function() { //這里的函數異步執行 if(xhr.readyState == 4) { if(xhr.status == 200) { alert(xhr.responseText); } } }; xhr.send(null);
readyState
- 0 - (未初始化)還沒有調用 send() 方法
- 1 - (載入)已調用 send() 方法,正在發送請求
- 2 - (載入完成)send() 方法執行完成,已經接收到全部響應的內容
- 3 - (交互)正在解析相應內容
- 4 - (完成)響應內容解析完成,可以在客戶端調用了
status
- 2xx - 表示成功處理請求。如 200
- 3xx - 需要重定向,瀏覽器直接跳轉
- 4xx - 客戶端請求錯誤,如 404
- 5xx - 服務器端錯誤
跨域
瀏覽器有同源策略,不允許 ajax 訪問其他域接口
條件:協議、域名、端口、有一個不同就算跨域
可以跨域的三個標簽
- <img src=xxx> (會有防盜鏈處理的情況)
- <link href=xxxx>
- <script src=xxx>
img 用於打點統計,統計網站可能是其他域,無兼容性問題;
link script 可以使用CDN,script 可用於 JSONP
JSONP 實現原理
<script> window.callback = function (data) { //這是我們跨域得到的信息 console.log(data); } </script> <script src="http://coding.m.imooc.com/aqi.js"></script> <!--以上將返回 callback({x:100, y:200})-->
服務器端設置 http header
//第二個參數填寫允許跨域的域名稱,不建議直接寫"*" response.setHeader("Access-Control-Allow-Origin", "http://a.com, http://b.com"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With"); response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); //接收跨域的cookie response.setHeader("Access-Control-Allow-Credentials", "true");
五、存儲
- 請描述一下 cookie, sessionStorage 和 localStorage 的區別
cookie
本身用於客戶端和服務器端通信
但是它有本地存儲功能,於是就被“借用”
使用 document.cooki = ... 獲取和修改即可
會攜帶到 ajax 中
用於存儲的缺點:
存儲量太小,只有4kb
所有 http 請求都帶着,會影響獲取資源的效率
API 簡單,需要封裝才能使用 document.cookie = ...
locationStorage 和 sessionStorage
HTML5 專門為存儲設計,最大容量 5M
不會攜帶到 ajax 中
API 簡單易用:
localStorage.setItem(key,value);
localStorage.getItem(key);
區別:sessionStorage 如果瀏覽器關閉會自動清理