從面試題看考察知識點(三)

Web API

DOM 操作 (Documwnt Object Model)

題目六

  • DOM 是那種基本的數(shù)據(jù)結(jié)構(gòu)
  • DOM 操作常用的 API 有哪些
  • DOM 節(jié)點的 attrproperty 有何區(qū)別

知識點

  1. 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樹
  1. 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選擇器返回所有匹配其中一個選擇器的元素。
  1. 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) 
  1. 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>
  1. 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操作

知識點

  1. navigator && screen
// navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf('chrome')
console.log(isChrome)

// screen
console.log(screen.width)
console.log(screen.height)
  1. 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ù)
  • 描述事件冒泡流程
  • 對于一個無限下拉加載圖片的頁面, 如何給每個圖片綁定事件
    • 使用代理

事件

知識點

  1. 通用事件綁定
// 普通事件綁定
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')
})
  1. 關于IE低版本的兼容性
  • IE低版本使用 attachEvent 綁定事件
  • IE低版本使用量非常少, 很多網(wǎng)站早已不支持
  • 要求低 IE ,放棄面試
  1. 事件冒泡
// 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('取消')
})
  1. 代理
<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)
  }
})
  1. 完善通用綁定事件的函數(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

知識點

  1. 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)
  1. IE 兼容性問題
  • IE 低版本使用 ActiveXObject, 和 W3C 標準不一樣
  1. readyState
  • 0 - (未初始化) 還沒有調(diào)用 send() 方法
  • 1 - (載入) 已調(diào)用 send() 方法, 正在發(fā)送請求
  • 2 - (載入完成) send() 方法執(zhí)行完成, 已經(jīng)接收到全部響應內(nèi)容
  • 3 - (交互) 正在解析響應內(nèi)容
  • 4 - (完成) 響應解析完成, 可以在客戶端調(diào)用
  1. status
  • 2xx - 表示成功處理請求, 如 200
  • 3xx - 需要重定向, 瀏覽器直接跳轉(zhuǎn)
  • 4xx - 客戶端請求錯誤, 如 404
  • 5xx - 服務端錯誤
  1. 跨域
  • 什么是跨域
    • 瀏覽器有同源策略, 不允許 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易用性

知識點

  1. cookie

    • 本身用于客戶端和服務端通信
    • 但是它有本地存儲的功能, 于是被 "借用"
    • 使用 document.cookie = ... 獲取和修改即可
  2. cookie用于存儲的缺點

    • 存儲量太小,只有 4kb
    • 所有 http請求都帶著, 會影響獲取資源的效率
    • API簡單, 需要封裝才能用 document.cookie = ...
  3. sessionStorage 和 localStorage

    • HTML5 專門為存儲設計, 最大容量 5M
    • API 簡單易用
    • localStorage.setItem(key,value)
    • localStorage.getItem(key)
    • IOS safari 隱藏模式下, localStorage.getItem會報錯
    • 建議統(tǒng)一使用 try-catch 封裝

從面試題看考察知識點(一)
從面試題看考察知識點(二)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標準。 注意:講述HT...
    kismetajun閱讀 28,804評論 1 45
  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化,入門級到專家級,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,682評論 0 7
  • 常見試題 行內(nèi)元素:會在水平方向排列,不能包含塊級元素,設置width無效,height無效(可以設置line-h...
    他大舅啊閱讀 2,620評論 1 5
  • 前端開發(fā)面試知識點大綱: HTML&CSS: 對Web標準的理解、瀏覽器內(nèi)核差異、兼容性、hack、CSS基本功:...
    秀才JaneBook閱讀 2,773評論 0 25
  • 請參看我github中的wiki,不定期更新。https://github.com/ivonzhang/Front...
    zhangivon閱讀 7,762評論 2 19

友情鏈接更多精彩內(nèi)容