前言
這是JS基本知識的第二篇菌湃,這篇小結(jié)主要是針對W3C標(biāo)準(zhǔn)展開。以下是前一篇小結(jié)和這篇的范圍:
- JS 基礎(chǔ)知識:ECMA 262標(biāo)準(zhǔn):變量類型、原型蒸矛、作用域、異步
- JS-Web-API: W3C標(biāo)準(zhǔn): 只管定義用于瀏覽器中JS操作頁面的API和全局變量扫外, 如JS內(nèi)置的全局函數(shù)和對象window, document, navigator莉钙。
這篇文章的主要內(nèi)容是小結(jié)于慕課網(wǎng)的視頻課程《前端JavaScript面試技巧》, 如有錯誤,請多指正筛谚,謝謝磁玉。
1. DOM操作
1.1 DOM概念
Document Object Model, 文檔對象模型抽莱。是一套操作HTML和XML文檔的API绊起。
1.2 DOM本質(zhì)
- 瀏覽器拿到html代碼后,DOM把html代碼結(jié)構(gòu)話瀏覽器可識別以及JS可識別的東西援雇。
- HTML代碼就是一個字符串吮铭,但是瀏覽器已經(jīng)把字符串結(jié)構(gòu)話樹形結(jié)構(gòu)了时迫。
1.3 DOM節(jié)點(diǎn)操作
- 獲取DOM節(jié)點(diǎn):
document,getElementById()
,document.getElementByTagName
,docuement.getElementsByClassName()
,document.querySelectorAll()
- DOM結(jié)構(gòu)操作
- 新增節(jié)點(diǎn)
document.createElement(node)
- 獲取父元素
childNode.parentElement
- 獲取子元素
parentNode.childNodes
- 刪除節(jié)點(diǎn)
parentNode.removeChild(childNode)
- 新增節(jié)點(diǎn)
1.4 property與Attribute的區(qū)別
- property: nodeName, 對象的屬性,修改的是html標(biāo)簽
- Attribute:
getAttribute()
,setAttribute()
, 文檔的屬性谓晌,修改的是標(biāo)簽里面的屬性
2. BOM操作
1.1 BOM理解
Browser Object Model掠拳, 瀏覽器對象模型。瀏覽器對象模型提供了獨(dú)立于內(nèi)容的纸肉、可以與瀏覽器窗口進(jìn)行互動的對象結(jié)構(gòu)溺欧。BOM由多個對象組成,其中代表瀏覽器窗口的Window對象是BOM的頂層對象柏肪,其他對象都是該對象的子對象姐刁。
1.2 四個比較重要的對象
navigator、screen烦味、location聂使、history, 以下是常用的API:
//navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf("Chrome")
console.log(isChrome)
//screen
console.log(screen.width)
console.log(screen.height)
//localtion
console.log(location.herf)
console.log(localtion.protocol)
console.log(location.pathname)
console.log(location.search)
console.log(location.hash)
//history
history.back()
history.forward()
3. 事件綁定
3.1 事件綁定之事件監(jiān)聽
事件綁定指的是事件處理程序。事件綁定一共有三種方法:行內(nèi)綁定(嵌入DOM的onclick)柏靶,動態(tài)監(jiān)聽(綁定DOM元素document.getElementById('btn').onclick
)弃理,事件監(jiān)聽, 以下是事件監(jiān)聽的事例(通用的事件監(jiān)聽函數(shù))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn1">click</button>
<a id="link1" herf="baidu.com">link1</button>
</body>
<script type="text/javascript">
//方法一
var btn = document.getElementById('btn1');
btn.addEventListener('click',function(event){
console.log('clicked');
})
//方法二(封裝addEventListener)
function bindEvent(elem, type, fn){
elem.addEventListener(type,fn)
}
var a = document.getElementById('link1')
bindEvent(a,'click',function(e){
e.preventDefault()//阻止默認(rèn)行為
alert('clicked')
})
</script>
</html>
3.2 事件冒泡流程
3.2.1 流程的理解
DOM元素自身事件被觸發(fā)后宿礁,會根據(jù)DOM樹形結(jié)構(gòu)一層一層地往父元素來冒泡案铺,如果有相同的事情,就會被觸發(fā)梆靖。另外控汉,在冒泡過程中,還可以阻止冒泡返吻。
3.2.2 事件冒泡的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<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>
</body>
<script type="text/javascript">
function bindEvent(elem, type, fn){
elem.addEventListener(type, fn);
}
var p1 = document.getElementById('p1')
var body = document.body
bindEvent(p1, 'click', function(e){
e.stopPropagation();//阻止冒泡
alert('激活')
})
bindEvent(body, 'click', function(e){
alert('取消')
})
</script>
</html>
- 解析:點(diǎn)擊p1時姑子,觸發(fā)了p1的事件,理論上會冒泡去觸發(fā)body綁定的事件测僵,但使用了e.stopPropagation()阻止了事件冒泡街佑,所以不會觸發(fā)body綁定的事件
3.3 代理
- 理解:事件代理, 也叫事件委托捍靠,就是利用事件冒泡沐旨,只制定一個時間處理程序,就可以管理某一類型的所有事件榨婆。
- 應(yīng)用:實(shí)現(xiàn)無限下拉加載圖片的頁面
- 好處:代碼簡潔磁携,瀏覽器壓力小
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="div1">
<a href="">a1</a>
<a href="">a2</a>
<a href="">a3</a>
<a href="">a4</a>
</div>
</body>
<script type="text/javascript">
var div1 = document.getElementById('div1')
div1.addEventListener('click',function(e){
var target = e.target;
if(target.nodeName === 'A'){
alert(target.innerHTML)
}
})
</script>
</html>
另外,IE低版本的兼容性(了解即可良风,無需深究):IE低版本使用attachEvent綁定事件谊迄,和W3C標(biāo)準(zhǔn)不一樣
3.4 最后編寫的一個通用綁定事件的函數(shù)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="div1">
<a href="">a1</a>
<a href="">a2</a>
<a href="">a3</a>
<a href="">a4</a>
</div>
</body>
<script type="text/javascript">
function bindEvent(elem, type, selector, fn){
if(fn == null){
fn = selector
selector = null
}
elem.addEventListenr(type, function(e){
var target
if(selector){
target = e.target
if(target.matches(selector)){
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('a1')
bindEvent(div1, 'click', function(e){
console.log(a.innerHTML)
})
</script>
</html>
4. ajax請求(http協(xié)議)
4.1 Ajax原生寫法: XMLHttpRequest
var xhr = new XMLHttpRequest()
xhr.open("Get", "/api", false)
xhr.onreadystatechange = function(){
//這里的函數(shù)是異步執(zhí)行的
if(xhr.readyState == 4){
if(xhr.status == 200){
alert(xhr.responseText)
}
}
}
xhr.send(null)
另外,IE低版本使用activeXObject
4.2 狀態(tài)碼說明
readState
- 0 - (未初始化) 還沒有調(diào)用send()方法
- 1 - (載入) 已調(diào)用send()方法烟央,正在發(fā)送請求
- 2 - (載入完成) send()方法執(zhí)行完成统诺,已經(jīng)接收到全部響應(yīng)內(nèi)容
- 3 - (交互) 正在解析相應(yīng)內(nèi)容
- 4 - (完成) 相應(yīng)內(nèi)容解析完成,可以在客戶端調(diào)用了
status - 2xx - 表示成功處理請求疑俭,如200
- 3xx - 需要重定向粮呢,瀏覽器直接跳轉(zhuǎn)
- 4xx - 客戶端請求錯誤,如404
- 5xx - 客戶端錯誤
4.3 跨域
定義
瀏覽器有同源策略钞艇,不充許ajax訪問其他域接口鬼贱。 協(xié)議, 域名香璃,端口,有一個不同就算跨域
可以跨域的三個標(biāo)簽
-
<img src=xxx>
用于打點(diǎn)統(tǒng)計(jì)舟误,統(tǒng)計(jì)網(wǎng)站可能是其他域 -
<ink href=xxx>
可以使用CDN葡秒, CDN的也是其他域 -
<script src=xxx>
可以用域JSONP
服務(wù)器端設(shè)置http header : 通過response.setHeader()
4.4 JSONP
實(shí)現(xiàn)原理: 瀏覽器有同源策略,不允許ajax訪問其他域的接口,有三個標(biāo)簽 img, link, script允許跨域眯牧,所以可以在自己的瀏覽器端定義一個函數(shù)A(如下面的callback函數(shù))蹋岩,用script src請求一個外域的API, API返回的是一個執(zhí)行函數(shù)A的片段(callback函數(shù)的執(zhí)行)学少,通過這種形式可以請求其他域的數(shù)據(jù)剪个。
<script type="text/javascript">
window.callback = function(data){
//這是跨域得到的信息
console.log(data)
}
</script>
<script src="http://coding.m.imooc.com/api.js"></script>
<!-- 以上將返回callback({x:100, y:200}) -->
5. 存儲
5.1 cookie
- 定義
本身用域客戶端和服務(wù)器端通信, 有本地存儲的功能版确,于是被“借用”扣囊, 使用document.cookie=獲取和修改 - 缺點(diǎn)
存儲量太小,只有4KB
所有http請求都帶著绒疗,會影響獲取資源的效率
API簡單侵歇,需要封裝才能用document.cookie=...
5.2 sessionStorage和localStorage
HTML5專門為存儲而設(shè)計(jì),最大容量5M
API簡單易用:localStorage.setItem(key, value), localStorage.getItem(key, value)
IOS safari隱藏模式下吓蘑,localStorage.getItem會報錯惕虑,建議統(tǒng)一用try-catch封裝
cookie, sessionStorage, localStorage的區(qū)別
容量,是否攜帶ajax中磨镶,API易容性溃蔫。