Web API
DOM 操作 (Documwnt Object Model)
題目六
-
DOM是那種基本的數(shù)據(jù)結(jié)構(gòu)- 樹
-
DOM操作常用的API有哪些 -
DOM節(jié)點的attr和property有何區(qū)別
知識點
-
DOM本質(zhì)
- 文檔對象模型 (DOM) 是HTML和XML文檔的編程接口。它給文檔(結(jié)構(gòu)樹)提供了一個結(jié)構(gòu)化的表述并且定義了一種方式—程序可以對結(jié)構(gòu)樹進行訪問,以改變文檔的結(jié)構(gòu),樣式和內(nèi)容。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<div>
<p>this is p</p>
</div>
</body>
</html>
DOM樹
- DOM 節(jié)點操作
- 獲取 DOM 節(jié)點
1. getElementById
var elem = document.getElementById("test") // 元素
2. getElementsByTagName
var paras = document.getElementsByTagName("p"); // 集合
3. getElementsByClassName
var elements = document.getElementsByClassName('tab'); // 類似數(shù)組的對象
4. getElementsByName // getElementsByName方法用于選擇擁有name屬性的HTML元素
// 假定有一個表單是<form name="x"></form>
var forms = document.getElementsByName("x");
forms[0].tagName // "FORM"
5. querySelector // querySelector方法返回匹配指定的CSS選擇器的元素節(jié)點。如果有多個節(jié)點滿足匹配條件,則返回第一個匹配的節(jié)點。如果沒有發(fā)現(xiàn)匹配的節(jié)點,則返回null。
var el1 = document.querySelector(".myclass");
var el2 = document.querySelector('#myParent > [ng-click]'); // querySelector方法無法選中CSS偽元素。
6. querySelectorAll // querySelectorAll方法返回匹配指定的CSS選擇器的所有節(jié)點,返回的是NodeList類型的對象。
var matches = document.querySelectorAll("div.note, div.alert"); //querySelectorAll方法的參數(shù),可以是逗號分隔的多個CSS選擇器返回所有匹配其中一個選擇器的元素。
-
property :js 對象的一個屬性
var pList = document.querySelectorAll('p')
var p = pList[0]
console.log(p.style.width) // 獲取樣式
p.style.width = '100px' // 修改樣式
console.log(p.classname) // 獲取class
// 獲取nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)
attribute :
var pList = document.querySelectorAll('p')
var p = pList[0]
p.getAttribute('data-name')
p.setAttribute('data-name', 'imooc')
p.getAttribute('style')
p.getAttribute('style', 'font-size: 30px')
// 文檔上的屬性標簽
<li class="li">
<a href="#" data-name="a"></a>
</li>
- DOM 結(jié)構(gòu)操作
- 新增節(jié)點
createElement
var div1 = document.getElementById('div1')
// 添加新節(jié)點
var p1 = document.createElement('p')
div1.appendChild(p1) // 添加新創(chuàng)建的元素
- 獲取父元素和子元素
parentElement childNodes
var div1 = document.getElementById('div1')
var parent = div1.parentElement
var child = div1.childNodes
div1.removeChild(child[0])
- 刪除節(jié)點
var child = div1.childNodes
div1.removeChild(child[0])
題目七
- 如何檢測瀏覽器的類型
function isAndroid(){ return /Android/.test(navigator.userAgent); } funcnction isIphone(){ return /iPhone/.test(navigator.userAgent); } function isIpad(){ return /iPad/.test(navigator.userAgent); } function isIOS(){ return /(iPad)|(iPhone)/i.test(navigator.userAgent); } - 解析
url各部分
BOM操作
知識點
-
navigator&&screen
// navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf('chrome')
console.log(isChrome)
// screen
console.log(screen.width)
console.log(screen.height)
-
location&&history
// location屬性返回一個只讀對象,提供了當前文檔的URL信息
// 假定當前網(wǎng)址為http://user:passwd@www.example.com:4097/path/a.html?x=111#part1
document.location.href //"http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
document.location.protocol // "http:"
document.location.host // "www.example.com:4097"
document.location.hostname // "www.example.com"
document.location.port // "4097"
document.location.pathname // "/path/a.html"
document.location.search // "?x=111"
document.location.hash // "#part1"
document.location.user // "user"
document.location.password // "passed"
// 跳轉(zhuǎn)到另一個網(wǎng)址
document.location.assign('http://www.google.com')
// 優(yōu)先從服務器重新加載
document.location.reload(true)
// 優(yōu)先從本地緩存重新加載(默認值)
document.location.reload(false)
// 跳轉(zhuǎn)到另一個網(wǎng)址,但當前文檔不保留在history對象中,
// 即無法用后退按鈕,回到當前文檔
document.location.assign('http://www.google.com')
// 將location對象轉(zhuǎn)為字符串,等價于document.location.href
document.location.toString()
// history
history.back()
history.forward()
題目八
- 編寫一個通用的事件監(jiān)聽函數(shù)
- 描述事件冒泡流程
- 對于一個無限下拉加載圖片的頁面, 如何給每個圖片綁定事件
- 使用代理
事件
知識點
- 通用事件綁定
// 普通事件綁定
var btn = document.getElementById('btn')
btn.addEventListener('click',function(event) {
console.log('clicked')
})
// 通用事件綁定
function bindEvent(el, type, fn) {
el.addEventListener(type, fn)
}
var a = document.getElementById('link')
bindEvent(a, 'click', function(e) {
e.preventDefault() // 阻止默認行為
console.log('clicked')
})
- 關于IE低版本的兼容性
- IE低版本使用
attachEvent綁定事件 - IE低版本使用量非常少, 很多網(wǎng)站早已不支持
- 要求低 IE ,放棄面試
- 事件冒泡
// html
<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>
// js
function bindEvent(el, type, fn) {
el.addEventListener(type, fn)
}
var p1 = document.getElementById('p1')
var body = document.body
bindEvent(p1, 'click', function(e) { // 會發(fā)生冒泡事件, stopPropagation阻止冒泡
e.stopPropagation()
console.log('激活')
})
bindEvent(body, 'click', function(e) { // 冒泡
console.log('取消')
})
- 代理
<div id="div1">
<a href="#" id="a1">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!- 會隨時新增更多 a 標簽 -->
</div>
var div = document.getElementById('div1')
div.addEventListener('click', function(e) {
var target = e.target
if (target.nodeName === 'A') {
console.log(target.innerText)
}
})
- 完善通用綁定事件的函數(shù)
function bindEvent(el, type, selector, fn) {
// 如果沒有第三個參數(shù), selector = fn
if (fn == null) {
fn = selector
selector = null
}
el.addEventListener(type, function (e) {
var target
if(selector) {
target = e.target
// dom 節(jié)點是否和選擇器匹配
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
fn(e)
}
})
}
// 使用代理
var div = document.getElementById('div1')
bindEvent(div, 'click', 'a', function (e) {
e.preventDefault() // 阻止默認行為
console.log(this.innerHTML)
})
// 不使用代理
var a = document.getElementById('a1')
bindEvent(a, 'click', function (e) {
e.preventDefault()
console.log(a.innerHTML)
})
題目九
- 手動編寫一個ajax, 不依賴第三方庫
- 跨域的幾種實現(xiàn)方式
Ajax
知識點
XMLHttpRequest
var xhr = new XMLHttpRequest()
xhr.open('GET', "/api", false)
xhr.onreadystatechange = function () {
// 這里的函數(shù)異步執(zhí)行
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText)
}
}
}
xhr.send(null)
- IE 兼容性問題
- IE 低版本使用
ActiveXObject, 和W3C標準不一樣
readyState
- 0 - (未初始化) 還沒有調(diào)用
send()方法 - 1 - (載入) 已調(diào)用
send()方法, 正在發(fā)送請求 - 2 - (載入完成)
send()方法執(zhí)行完成, 已經(jīng)接收到全部響應內(nèi)容 - 3 - (交互) 正在解析響應內(nèi)容
- 4 - (完成) 響應解析完成, 可以在客戶端調(diào)用
status
-
2xx- 表示成功處理請求, 如 200 -
3xx- 需要重定向, 瀏覽器直接跳轉(zhuǎn) -
4xx- 客戶端請求錯誤, 如 404 -
5xx- 服務端錯誤
- 跨域
- 什么是跨域
- 瀏覽器有同源策略, 不允許
ajax訪問其他域接口 - 跨域條件 : 協(xié)議 域名 端口 有一個不同就算跨域
- 瀏覽器有同源策略, 不允許
- 可以跨域的三個標簽
<img src="xxx"><link href="xxx"><script src="xxx">
- 三個標簽的場景
-
<img>用于打點統(tǒng)計, 統(tǒng)計網(wǎng)站可能是其他域 -
<link><script>可以使用CDN,CDN的也是其他域 -
<script>可以用于JSONP
-
- 跨域注意事項
- 所有的跨域都必須經(jīng)過信息提供方允許
- 如果未經(jīng)允許, 那是瀏覽器同源策略出現(xiàn)漏洞
-
JSONP 實現(xiàn)原理-
jsonp全稱是JSON with Padding,是為了解決跨域請求資源而產(chǎn)生的解決方案。 - 加載
http://xxx/a.html, 不一定服務端真正有一個a.html文件, 服務端可以根據(jù)請求,動態(tài)生成一個文件,返回 - 同理于
<script src="http://xxx.com/api.js">
<script> window.callback = function (data) { // 這里是我們跨域得到信息 console.log(data) } </scrpt> // 下面返回callback({x:100, y: 200}) <script src="http://xxx.com/api.js"> function getBooks(){ var script=document.createElement('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src','http://test.com/bookservice.php?callback=displayBooks'); // 重點 callback= xxx document.body.appendChild(script); } getBooks(); -
服務器端設置
http header
// 第二個參數(shù)寫跨域名稱, 不建議直接寫 "*"
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的區(qū)別 ?- 容量
- 是否在
ajax中 -
API易用性
知識點
-
cookie- 本身用于客戶端和服務端通信
- 但是它有本地存儲的功能, 于是被 "借用"
- 使用
document.cookie = ...獲取和修改即可
-
cookie用于存儲的缺點- 存儲量太小,只有 4kb
- 所有
http請求都帶著, 會影響獲取資源的效率 -
API簡單, 需要封裝才能用document.cookie = ...
-
sessionStorage 和 localStorage-
HTML5專門為存儲設計, 最大容量5M - API 簡單易用
localStorage.setItem(key,value)localStorage.getItem(key)-
IOS safari隱藏模式下,localStorage.getItem會報錯 - 建議統(tǒng)一使用
try-catch封裝
-