【前端知識體系-JS相關】JS-Web-API總結

2.1 DOM操做

2.1.1 DOM的本質是什麼?

<!-- DOM樹:二叉樹 -->
    /*
    <?xml version="1.0" encoding="UTF-8">               // 告訴瀏覽器以哪種類型進行解析
    <node>
        <child />
    </node>
     */

    <!DOCTYPE html>                                      // 以html類型進行解析文檔內容
    <html>
        <body>

        </body>
    </html>

2.1.2 DOM操做的經常使用API有哪些?

節點查找API

  1. document.getElementById :根據ID查找元素,大小寫敏感,若是有多個結果,只返回第一個;
  2. document.getElementsByClassName :根據類名查找元素,多個類名用空格分隔,返回一個 HTMLCollection 。注意兼容性爲IE9+(含)。另外,不只僅是document,其它元素也支持 getElementsByClassName 方法;
  3. document.getElementsByTagName :根據標籤查找元素, * 表示查詢全部標籤,返回一個 HTMLCollection 。
  4. document.getElementsByName :根據元素的name屬性查找,返回一個 NodeList 。
  5. document.querySelector :返回單個Node,IE8+(含),若是匹配到多個結果,只返回第一個。
  6. document.querySelectorAll :返回一個 NodeList ,IE8+(含)。
  7. document.forms :獲取當前頁面全部form,返回一個 HTMLCollection ;

節點建立API

  1. createElement建立元素
  2. createTextNode建立文本節點
  3. cloneNode 克隆一個節點
  4. createDocumentFragment

節點修改API

  1. appendChild
  2. insertBefore
  3. insertAdjacentHTML
  4. Element.insertAdjacentElement()
  5. removeChild
  6. replaceChild

節點關係API

  • 一、父關係API

parentNode :每一個節點都有一個parentNode屬性,它表示元素的父節點。Element的父節點多是Element,Document或DocumentFragment;
parentElement :返回元素的父元素節點,與parentNode的區別在於,其父節點必須是一個Element元素,若是不是,則返回null;html

  • 二、子關係API

children :返回一個實時的 HTMLCollection ,子節點都是Element,IE9如下瀏覽器不支持;node

childNodes :返回一個實時的 NodeList ,表示元素的子節點列表,注意子節點可能包含文本節點、註釋節點等;面試

firstChild :返回第一個子節點,不存在返回null,與之相對應的還有一個 firstElementChild ;ajax

lastChild :返回最後一個子節點,不存在返回null,與之相對應的還有一個 lastElementChild ;express

  • 三、兄弟關係型API

previousSibling :節點的前一個節點,若是不存在則返回null。注意有可能拿到的節點是文本節點或註釋節點,與預期的不符,要進行處理一下。json

nextSibling :節點的後一個節點,若是不存在則返回null。注意有可能拿到的節點是文本節點,與預期的不符,要進行處理一下。後端

previousElementSibling :返回前一個元素節點,前一個節點必須是Element,注意IE9如下瀏覽器不支持。api

nextElementSibling :返回後一個元素節點,後一個節點必須是Element,注意IE9如下瀏覽器不支持。跨域

元素屬性型API

一、setAttribute 給元素設置屬性:
二、getAttribute
三、hasAttribute瀏覽器

樣式操做API(面試考點)

  • 一、直接修改元素的樣式
elem.style.color = 'red';  
elem.style.setProperty('font-size', '16px');  
elem.style.removeProperty('color');
  • 二、動態添加樣式規則
var style = document.createElement('style');  
style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';  
document.head.appendChild(style);
  • 三、classList獲取樣式屬性

    [!NOTE]
    瞭解dom節點樣式(classList)的remove, add, toggle, contains, replace等方法的使用。

  • 四、window.getComputedStyle
    經過 element.sytle.xxx 只能獲取到內聯樣式,藉助 window.getComputedStyle 能夠獲取應用到元素上的全部樣式,IE8或更低版本不支持此方法。

var style = window.getComputedStyle(element[, pseudoElt]);

2.1.3 DOM節點的attr和proerty的區別

// proprty------>>>獲取nodeName和nodeType(property實際上就是JS對象的一個屬性)如:text : 3(#text), p : 1(p)
    console.log(pList[0].nodeName);         // p
    console.log(pList[0].nodeType);         // 1
// attribute------>>> 獲取一個HTML標籤的屬性信息(設置和修改)
    var a = document.getElementsByTagName('a')[0];
    console.log(a.getAttribute('data-origin'));
    console.log(a.getAttribute("href_name"));           // 能夠給一個HTML標籤設置任意的屬性名稱,不管這個屬性內部是否存在
a.  setAttribute('sex', 'male')
// 區別:
// (JS對象&HTML標籤)property其實是一個普通JS對象自己的基本屬性,可是attribute其實是一個HTML標籤上面的屬性信息

[!NOTE]
區別:(JS對象&HTML標籤)property其實是一個普通JS對象自己的基本屬性,可是attribute其實是一個HTML標籤上面的屬性信息

2.2 BOM操做

2.2.1 如何檢測瀏覽器的類型?

var ua = navigator.userAgent;
    var isChrome = ua.indexOf('Chrome');
    console.log('is Chrome?', isChrome > 0, navigator.userAgent);
    console.log('電腦屏幕大小:', screen.width, screen.height)

2.2.2 如何拆解URL的各個部分?

// location
    console.log(location.href);                 // 完整的url地址,http://localhost:8080/JS-Professional/begin/02-%E5%9F%BA%E7%A1%80%E8%BF%9B%E9%98%B6/01-%E4%BB%8E%E5%9F%BA%E7%A1%80%E5%88%B0%E8%BF%9B%E9%98%B6.html?_ijt=i8ctmkc87dvh03tdaf51rn5v1i
    console.log(location.protocol)              // http/https
    console.log(location.host, location.hostname)                  // www.52tech.tech
    console.log(location.pathname);             // host以後的所有內容,JS-Professional/begin/02-%E5%9F%BA%E7%A1%80%E8%BF%9B%E9%98%B6/01-%E4%BB%8E%E5%9F%BA%E7%A1%80%E5%88%B0%E8%BF%9B%E9%98%B6.html
    console.log(location.search);               // search就是?以後的所有內容,?_ijt=i8ctmkc87dvh03tdaf51rn5v1i(包括?)
    console.log(location.hash);                 // #後面的內容(包括#)

2.3 事件操做

2.3.1 編寫一個通用的事件監聽函數

function bindEvent(ele, type, selector, fn){
        if (fn == null) {
            fn = selector;
            selector = null;
        }

        // addEventListener 的最後一個參數默認是false, 表示的是事件冒泡,自下向上去捕獲事件,true:表示事件捕獲,表示事件自外向裏的方式
        ele.addEventListener(type, function(e){
            if (selector) {
                // 使用的是代理的方式的話
                if (e.target.matches(selector)){            // 這裏須要去判斷當前點擊的那個對象是否是我點擊的那個對象
                    fn.call(e.target, e);
                }
            } else {
                // 不使用代理的話
                fn(e);
            }
        });
    }


    // 這裏表示對這個div1 內部的全部的a標籤使用事件冒泡
    bindEvent(document.getElementById('div4'), 'click', 'p', function (e) {
        console.log(this.innerHTML + 'hahaah')
    })
版本2:
/**
     * 實現一個通用的事件綁定函數(代碼簡潔,減小了瀏覽器的佔用)
     * @param element
     * @param type
     * @param selector
     * @param fn
     */
    function bindEvent(element, type, selector, fn) {
        // if (fn === null || fn === undefined)        // 這裏能夠直接優化爲fn == null
        if (fn == null){
            // 只有3個參數的話
            fn = selector;
            selector = null;
        }

        element.addEventListener(type, function (e) {
            var target;
            // 若是selector有的話,說明此事element就是一個代理
            if (selector) {
                target = e.target;
                // 若是當前的target知足這個選擇器的話
                // 若是元素被指定的選擇器字符串選擇,Element.matches()  方法返回true; 不然返回false。
                // document.getElementById('div1').matches('div')    true
                // matches裏面的參數其實是一個HTML標籤:a, p, div …………, 內容也是不區分大小寫的,有點相似於nodeName 或者nodeType 這樣的判斷
                if (target.matches(selector)){
                    // 修改this的指向
                    fn.call(target, e);
                }
            }else {
                fn(e);
            }
        });
    }

2.3.2 描述事件冒泡的流程

[!NOTE]
"DOM2級事件」規定的事件流包含三個階段:事件捕獲階段,處於目標階段和事件冒泡階段。首先發生的是事件捕獲,而後是實際的目標接收到事件,最後階段是冒泡階段。

  • 事件冒泡:
    按照DOM樹形結構向上冒泡(p --- >>> div --- >>> body --- >>> document),
  • 事件捕獲
    (document—>—>—>
    的順序進行傳播的)

2.3.3 對於一個無線下拉圖片的頁面,如何給每個圖片綁定一個事件

// 代理(div3裏面的全部a標籤都須要進行事件的監聽)
    var div3 = document.getElementById('div3');
    bindEvent(div3, 'click', function (e) {
        e.preventDefault();
        e.stopPropagation()
        // 能夠獲取真實觸發的那個元素
        var target = e.target;
        console.log(target.nodeName, target.nodeType);      // 每一種頁面標籤實際上都有一個本身專屬的nodeName
        // 這裏的目的主要是用於過濾,只處理a標籤的事件處理
        if ('A' === target.nodeName) {
            //  若是當前點擊的a標籤就是本身
            alert(target.innerHTML)
        }
    })

2.4 Ajax操做

2.4.1 手動編寫一個ajax,不依賴第三方庫

2.4.2 跨域的幾種實現方式以及底層的實現原理

  1. 服務器端的使用:response.setHeader(Access-Control-Allow-Origin, "http://www.baidu.com, http://www.52tech.tech")容許跨域
  2. 使用JSONP

2.4.3 JSONP的實現原理

[!NOTE]
跨域:瀏覽器有同源策略,不容許ajax訪問其餘域接口

  • 跨域條件:協議、域名、端口,有一個不一樣就是跨域

能夠跨域加載資源的3個標籤:

<img src="">, <link href="">, <script src="">
  • img用途:主要用於打點統計,統計網站多是其餘域
  • link, script用途:可使用CDN,可使用其餘域
  • script用途:能夠用於JSONP

2.4.3.1 跨域注意事項:

  1. 全部的跨域請求都必須通過信息提供方的容許才能夠獲取
  2. 若是未經容許就能夠直接獲取,就是瀏覽器的同源策略出現漏洞

2.4.3.2 瀏覽器端實現(提早定義一個回調函數)

//封裝一個jsonp請求的函數
  function query(opt) {
      let str = ""
      for (let key in opt) {
          str += key + "=" + opt[key] + "&"
      }
      return str
  }
  //設置默認回調函數的名字
  const defaultOptions = {
      callbackName: "callback"
  }
  function jsonp(url, opt, options = defaultOptions) {
      //參數解析  URL爲訪問的接口 opt爲傳播的數據  option 爲接受參數的回調函數
      return new Promise((resolve, reject) => {
          //判斷下這個?是否是存在
          let index = url.indexOf("?");
          url += index != -1 ? query(opt) : "?" + query(opt);
          url = url + `${options.callbackName}=${options.callbackName}`;
          //首先創造一個標籤 帶有src的
          const scriptDom = document.createElement("script");
          //設置其src屬性
          scriptDom.setAttribute("src", url);
          //在window系統上建立一個回調函數用來接受數據
          window[options.callbackName] = (res) => {
              //在接受到了參數動態刪除這個script節點和window上面的方法
              delete window[options.callbackName];
              document.body.removeChild(scriptDom)
              //接受成功後調用resolve
              if (res) {
                  resolve(res)
              } else {
                  reject("服務器暫沒有獲取到數據")
              }
          }
          //動態建立script標記,錯誤的監聽
          scriptDom.addEventListener('error', () => {
              delete window['jsonpCallback'];
              document.body.removeChild(script);
              reject('服務器加載失敗!');
          });
          document.body.append(scriptDom)
      })
  }

2.4.3.3 後端實現

const url = require("url")

router.get("/api", (req, res, next) => {
  //將script標籤的src的URL請求轉成對象
  const opj = url.parse(req.url, true).query;
  //而後原理就是調用這個回調函數來進行傳參
  let {
    callback
  } = opj;
  //若是這個回調函數存在證實是jsonp請求
  if (callback) {
    let resault = JSON.stringify({
      code: 1,
      msg: "express框架傳回去的參數"
    });
    res.send(`${callback}(${resault})`)
  }
})

2.5 本地存儲

  1. 存儲量,只有4kb
  2. 全部的http請求都會帶有cookie,會直接影響獲取資源效率
  3. API,document.cookie

localstorage

  1. localstorage.setItem(key, value);localstorage.getItem('key');
  2. 存儲量5MB
  3. sessionStorage:會話級別

    [!WARNING] 【坑】IOS safari的隱藏模式下,使用localStorage.getItem('key') 會報錯,建議使用try{}catch(e){} 來實現能夠防止報錯

相關文章
相關標籤/搜索