前端知識點總結——DOM

前端知識點總結——DOM

1.什麼是DOM: Document Object Model

什麼是: 專門操作網頁內容的API標準——w3c
爲什麼: 統一不同瀏覽器操作網頁內容的API標準
優點: 幾乎所有瀏覽器100%兼容

2.DOM Tree:

什麼是: 網頁中所有內容在內存中都是保存在一棵樹形結構中
網頁中每項內容(元素,文本,屬性,註釋…),都是樹上的一個節點對象。
唯一的樹根節點: document
爲什麼: 樹形結構是最好的保存上下級包含關係的結構

節點對象: Node
網頁中每項內容都是DOM樹上的一個節點對象:
所有節點都有的三個屬性:
nodeType: 節點類型

何時: 只要判斷節點的類型時
包括: 
  document  9
  element    1
  attribute   2
  text       3
問題: 無法進一步區分元素的標籤名

nodeName: 節點名稱

何時: 只要進一步判斷元素的標籤名時
    ——可代替nodeType
包括:
 document   #document
 element     全大寫標籤名
 attribute     屬性名——不常用!
 text        #text

nodeValue: 節點值 ——不常用

 document  null
 element    null
 attribute   屬性值
 text       文本內容

3.查找: 4種:

1.不需要查找可直接獲得節點:
document.documentElement html
document.head head
document.body body
document.forms[id/i] form

2.按節點間關係查找:
何時: 如果已經獲得一個節點了。想找周圍節點時。
包括: 2種樹:

  1. 節點樹: 包含網頁中所有內容的完整樹結構
    2大類關係:
    1.父子: 4種:
    elem.parentNode elem的父節點
    elem.childNodes elem的直接子節點
    elem.firstChild elem下的第一個直接子節點
    elem.lastChild elem下的最後一個直接子節點
    2.兄弟: 2種:
    elem.previousSibling elem的前一個兄弟元素
    elem.nextSibling elem的後一個兄弟元素
    問題: 受看不見的空字符的干擾!

2.元素樹: 僅包含元素節點的樹結構
2大類關係:

  1. 父子: 4種:
    elem.parentElement elem的父元素
    elem.children elem的直接子元素
    elem.firstElementChild elem下的第一個直接子元素
    elem.lastElementChild elem下的最後一個直接子元素

2.兄弟: 2種:

elem.previousElementSibling  elem的前一個兄弟元素
elem.nextElementSibling      elem的後一個兄弟元素

今後只要用DOM操作網頁內容,都用元素樹
說明: 元素樹不是一棵新樹,其實只是節點樹的一個子集

childNodes和children: 動態集合(live collection)
什麼是: 不實際存儲屬性值,每次訪問集合都重新查找DOM樹
優: 首次查找,效率高! 因爲不用返回完整的屬性。
缺: 每次訪問集合,都會重新查找DOM樹,降低效率
遍歷:
不好: for(var i=0;i<children.length;i++){…}
好: for(var i=0,len=children.length;i<len;i++){…}

遍歷指定父元素下的所有後代元素: 2種:
1.遞歸: 2步:
1.定義函數僅遍歷指定父元素下的所有直接子元素
2.對每個直接子節點調用和父節點完全相同的操作
深度優先: 當一個節點同時擁有子節點和兄弟節點時,總是優先遍歷子節點。
所有子節點遍歷完,才返回遍歷兄弟節點。
2.循環: 2步:
1.定義迭代器:

 迭代器: 可以依次獲得每個後代元素節點的 專門對象
 如何: 
  創建: var iterator=document.createNodeIterator(
    parent, NodeFilter.SHOW_ELEMENT, null, false
  );

2.循環調用迭代器,獲得下一個節點對象:

 var curr=iterator.nextNode()
 內置深度優先遍歷的算法
 如果curr返回null,說明遍歷結束

3.按HTML查找: 4種:
1.按id查找:

var elem=document.getElementById("id")
返回值: 一個元素
  如果找不到返回null!
強調: 1. 只能在document上調用

2.按標籤名查找:

var elems=parent.getElementsByTagName("標籤名")
返回值: 多個元素的集合
  如果找不到返回空集合
強調: 1\. 可在任意父元素上調用
     2\. 不但找直接子元素,且在所有後代中查找

3.按name查找:

var elems=document.getElementsByName("name")
返回值: 多個元素的集合
  如果找不到返回空集合
強調: 只能在document上調用

4.按class查找:

var elems=parent.getElementsByClassName("class")
返回值: 多個元素的集合
  如果找不到返回空集合
強調: 1.可在任意父元素上調用
     2.不但找直接子元素,且在所有後代中查找
     3.只要元素的一個class名匹配,就能找到該元素
      強調: 返回的集合都是動態集合
      問題: 每次只能按一個條件查找
      當查找條件複雜時,步驟很繁瑣
      解決: 用選擇器查找:
web前端開發直播教程Q羣: 767273102 ,內有米免費開發工具,零基礎,進階視頻教程,希望新手少走彎路 

4.用選擇器查找:

1.僅查找一個符合條件的:

var elem=parent.querySelector("選擇器")
返回值: 一個元素
  如果找不到,返回null

2.查找多個符合條件的元素:

var elems=parent.querySelectorAll("選擇器")
返回值: 多個元素的集合
  如果找不到返回空集合
  返回非動態集合: 實際存儲屬性值,即使反覆訪問集合,
  也不會導致反覆查找DOM樹
強調: 1\. 可在任何父元素上調用
     2\. 選擇器只要相對於當前父元素內部即可
     3\. 選擇器的兼容性,受制於當前瀏覽器的兼容性

鄙視: 按HTML查找和按選擇器查找的差別:

1.返回值: 按HTML查找返回動態集合
          按選擇器查找返回非動態集合
2.效率: 首次查找: 按HTML查找效率高
                 按選擇器查找效率低
3.易用性: 按HTML查找繁瑣
          按選擇器查找簡單

總結: 今後,只要一個條件即可找到想要的元素,首選按HTML查找

只要查找條件複雜,都選按選擇器查找

jQuery中就是這麼選擇的

5.修改:

內容: .innerHTML .textContent .value
屬性: 3種:
1.HTML標準屬性: 2種:
1.核心DOM: 最初的DOM API,要求支持所有結構化文檔

  優: 幾乎萬能   缺: 繁瑣
 獲取屬性節點: var attrNode=elem.attributes[i]
 獲取屬性值: attrNode.value
   其實可以一步: var value=elem.getAttribute("屬性名")
 修改屬性值: elem.setAttribute("屬性名","值")
 移除屬性: elem.removeAttribute("屬性名")
 判斷是否包含指定屬性: elem.hasAttribute("屬性名")

2.HTML DOM: 專門操作HTML內容的API

            對核心DOM 常用API的簡化
 優: 簡單   缺: 不是萬能
 簡化: HTML DOM提前將所有標準屬性,封裝在了元素對象上,可用.直接訪問.
  比如:
    獲取屬性值: elem.屬性名
    修改屬性值: elem.屬性名="值"
     移除屬性: elem.屬性名=""
     判斷是否包含指定屬性: elem.屬性名!==""
 特例: class屬性: 
   ES的對象中已經先入爲主的包含了內部屬性class,用來記錄對象創建時的類型名。
   HTML的class屬性就無法同時存在
 所以: DOM: html的class屬性,更名爲className
 web前端開發直播教程Q羣: 767273102 ,內有米免費開發工具,零基礎,進階視頻教程,希望新手少走彎路 

2.狀態屬性: disabled selected checked
1.不能用核心DOM修改: 因爲值是bool類型
2.只能用HTML DOM,打.修改
3.自定義擴展屬性:
何時: 2種:

 1\. 在元素上保存自定義數據
 2\. 代替其他選擇器,用來查找元素綁定事件

如何: 2套:

 不能用HTML DOM訪問, 因爲不是標準屬性,未被提前封裝在DOM元素對象中
 1. 普通屬性名+核心DOM
 2. HTML5: 
  定義屬性時: data-屬性名="值"
  獲取或修改屬性值: elem.dataset.屬性名

固定用法: 用自定義擴展屬性代替其它選擇器,爲元素綁定事件

 爲什麼: 
   id: 唯一
   class: 經常變化
   elem: 做一種效果,可能使用任何元素
 解決: 今後,只要給元素綁定事件時,都要先爲元素添加自定義擴展屬性,
 再用自定義擴展屬性查找元素,綁定事件
  優: 沒有個數限制, 不會受樣式影響而變化,不受元素限制
 如何: 
  定義: data-屬性名="值"
  查找: 只能用屬性選擇器查找:[data-屬性名=值]

6.樣式: 2種:

1.內聯樣式:

修改: elem.style.css屬性名
 強調: 1. css屬性名都要去橫線變駝峯
      2.長度數值必須加px單位
獲取: 
 問題: 不能用elem.style.css屬性名
 原因: elem.style僅包含內聯樣式! 無法獲得內部或外部樣式表中的樣式
 解決: 獲取計算後的樣式!
  計算後的樣式: 最終應用到元素上的所有樣式的集合
                且將相對值換算爲絕對值
  何時: 只要獲取樣式時,都要獲取計算後的樣式
  如何: 2步:
    1. 獲得計算後的style對象:
      var style=getComputedStyle(elem);
    2. 從style中獲得css屬性值
      var value=style.css屬性值
  強調: getComputedStyle獲得樣式都是隻讀!

2.內部/外部: 3步:
1.獲得樣式表對象:

var sheet=document.styleSheets[i];

2.獲得樣式表對象中的cssRule

 什麼是cssRule: 樣式表中每個{}就是一個cssRule
 如何獲得: var rule=sheet.cssRules[i]

3.獲得cssRule中的style對象的css屬性

var value=rule.style.css屬性

問題: 用elem.style.css屬性一句話只能修改一個css屬性

如果同時修改多個屬性,代碼會很繁瑣

解決: 用class批量應用樣式
如何: 2步:

  1. 在css中準備好各種class
  2. 用程序,在對應情況下,選擇對應的class應用!
    web前端開發直播教程Q羣: 767273102 ,內有米免費開發工具,零基礎,進階視頻教程,希望新手少走彎路

7.添加:

添加: 3步:

  1. 創建空元素
    var a=document.createElement(“a”);

2.設置必要屬性
a.href=“http://tmooc.cn”;
a.innerHTML=“go to tmooc”;
3.將新元素添加到DOM樹:3種api:
parent.appendChild(a) 將a追加到指定父元素下末尾
parent.insertBefore(a, child) 將a插入到指定父元素下的現有子元素之前
parent.replaceChild(a, child) 用a替換指定父元素下的現有子元素

優化: 儘量減少操作DOM樹的次數, 從而減少重排重繪
爲什麼:
HTML頁面加載過程:
html -> DOM Tree

       ↓
      Render Tree -> ***layout -> paint
       ↑

css -> cssRules
如何:

  1. 如果同時添加父元素和子元素時,應先在內存中,將所有子元素添加到父元素中,
    再最後一次性將父元素添加到頁面上

8.刪除:

優化: 儘量減少操作DOM樹的次數
爲什麼: 減少重排重繪
如何: 2種:
1.如果同時添加父元素和子元素,則應該現在內存中,將子元素添加到父元素,再最後將父元素一次性整體添加到DOM Tree
2.如果父元素已經在頁面上了,要添加多個平級子元素,則應該使用文檔片段:

什麼是文檔片段: 內存中臨時存儲多個子元素的虛擬父元素
何時: 只要向網頁中同時添加多個平級子元素時,都可用文檔片段
如何: 3步:
 1.創建文檔片段
 2.將子元素添加到文檔片段
 3.將文檔片段整體添加到DOM 樹

刪除: parent.removeChild(child)

通常: child.parentNode.removeChild(child)

9.HTML DOM常用對象:

Image: 創建: var img=new Image();

Select: 代表頁面上一個select元素
屬性:
.selectedIndex 獲得當前select選中的option的下標位置
.value 獲得select中選中的option的值

如果選中的option沒有value屬性,則用innerHTML代替

.options 獲得當前select下所有option的集合

 .options.length 獲得select下所有option的個數
  .options.length=0

.length => .options.length

清空所有option .length=0

方法: .add(option) 追加一個option

    問題: .add不支持文檔片段
  .remove(i) 移除i位置的option

Option: 代表select下一個option元素
創建: var opt=new Option(text,value)
屬性: .text .value .index

Table: 代表一個table元素
管着行分組:
創建行分組: var thead=table.createTHead()

          var tbody=table.createTBody()
          var tfoot=table.createTFoot()

刪除行分組: table.deleteTHead()

table.deleteTFoot()

獲取行分組: table.tHead table.tFoot table.tBodies[i]
行分組: 管着行:
添加行: var tr=行分組.insertRow(i)

   在i位置插入一個新行
   固定套路: 1\. 在末尾追加新行: .insertRow()
            2\. 在開頭插入新行: .insertRow(0)

刪除行: 行分組.deleteRow(i) ——不常用!

    問題: i要求是在當前行分組內的相對下標位置
         無法自動獲得
    應換爲: table.deleteRow(tr.rowIndex)
     tr.rowIndex可自動獲得當前行在整個table內的位置

獲取行: 行分組.rows[i]
行: 管着格
添加格: var td=tr.insertCell(i)

固定用法: 行末尾追加一個格: tr.insertCell()
說明: 只能創建td,不能創建th

刪除格: tr.deleteCell(i)
獲取格: tr.cells[i]

Form: 代表一個form元素
獲取: var form=document.forms[i/id]
屬性: .elements 獲得表單中所有表單元素的集合
web前端開發直播教程Q羣: 767273102 ,內有米免費開發工具,零基礎,進階視頻教程,希望新手少走彎路

     .elements.length  獲得表單中,表單元素的個數
   .length => .elements.length

方法: .submit() 代替submit按鈕,在程序中實現手動提交表單

表單元素:
獲取: form.elements[i/id/name]

更簡化: form.name

方法: .focus 讓當前表單元素獲得焦點

發佈了42 篇原創文章 · 獲贊 150 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章