dom操作總結

關于dom操作,我們分創建、增、刪、改、查、屬性操作、事件操作來大體介紹一下


創建

1.createElement:通過傳入標簽來創建一個dom

demo

var node=document.createElement('div')
node.innerHTML='我是新增的node'
document.body.appendChild(node)

2.createTextNode:用來創建一個文本節點

demo

var node=document.createTextNode('我是新增的文本節點')
document.body.appendChild(node)

3.cloneNode:克隆一個節點,有一個參數,true支持深度克隆,false不支持深度克隆

demo

  <div id="div1">我是一個dom
    <span>我是一個子節點</span>
  </div>
  <script type="text/javascript">
  var cn = document.querySelector('#div1').cloneNode()
  var cn2 = document.querySelector('#div1').cloneNode(true)
  console.log(cn)
  console.log(cn2)
  </script>

淺拷貝的結果為

<div id="div1"></div>

深拷貝的結果為

<div id="div1">我是一個dom
    <span>我是一個子節點</span>
</div>

4. createDocumentFragment: 用來插入一段dom

這個方法的運用,可以減少頁面的重繪與回流問題,能批量的插入dom
demo

  var temp = document.createDocumentFragment()
  var a = document.createElement('div')
  a.innerHTML = 'It\'s a'
  var b = document.createElement('span')
  b.innerHTML = 'It\'s b'
  temp.appendChild(a)
  temp.appendChild(b)
  document.body.appendChild(temp)

添加到body之前,都沒有真正的加入到dom tree里面,避免了重繪與回流


1.appendChild

A.appendChild(B):將B添加到A子元素的最后一個位置,如下
默認的dom結構

  <div id="parent">
    <span>我是一開始就有的子節點</span>
  </div>

執行以下的js之后

  var parent = document.querySelector('#parent')
  var child = document.createElement('div')
  child.innerHTML = '我是子節點'
  parent.appendChild(child)
<div id="parent">
  <span>我是一開始就有的子節點</span>
  <div>我是子節點</div>
</div>

2.insertBefore

parent.insertBefore(newNode, exitsNode):將newNode添加到exitsNode的前面
默認dom結構

<div id="me">
    <div>child</div>
    <div>child2</div>
    <div>child3</div>
    <div>child4</div>
    <div>child5</div>
    <div>child6</div>
    <div>child7</div>
  </div>
<input type="number">
<button>新增一個孩子</button>

執行以下的js代碼,填入一個數字,點擊按鈕之后

  function addNode() {
    var index = document.querySelector('input').value
    var tempDom = document.createElement('div')
    tempDom.innerText = '我是新增的孩子'
    var me = document.querySelector('#me')
    var children = me.querySelectorAll('div')
    me.insertBefore(tempDom, children[index])
  }
  document.querySelector('button').addEventListener('click', addNode)
<div id="me">
    <div>child</div>
    <div>child2</div>
    <div>child3</div>
    <div>我是新增的孩子</div>
    <div>child4</div>
    <div>child5</div>
    <div>child6</div>
    <div>child7</div>
  </div>

注:如果第二個參數不存在或者異常,則會插入到最后

3.insertAdjacentElement

它包括兩個參數,其中第二個參數是要加的子節點,核心在于第一個參數,有如下的取值

beforebegin:把第二個參數加到當前節點的前面
afterend:把第二個參數加到當前節點的后面
afterbegin:把第二個參數加到當前節點的第一個子節點位置
beforeend:把第二個參數加到當前節點的最后一個節點的位置

一開始我看到這個也是懵逼的,其實記這個可以掌握一定的技巧,以beforebegin,和afterbegin來記,首先,begin肯定是在前面,before肯定也是在前面,就是兩個前面,就在節點前加,我就不類推了


1.removeChild

parent.removeChild(child),刪除parent下的child節點,并且返回這個節點
dom結構如下

 <div id="deleteDemo">
    <div>第一個子節點</div>
    <div>第二個子節點</div>
    <div>第三個子節點</div>
    <div>第四個子節點</div>
  </div>
  <input type="number" id="txtDeleteIndex" />
  <button id="btnDelete">刪除一個孩子</button>

執行以下的js代碼,輸入一個數字,并點擊按鈕

 function deleteNode() {
    var index = document.querySelector('#txtDeleteIndex').value
    var deleteDemo = document.querySelector('#deleteDemo')
    var children = deleteDemo.querySelectorAll('div')
    var removeChild = children[index] && deleteDemo.removeChild(children[index])
    console.log(removeChild)
  }
  document.querySelector('#btnDelete').addEventListener('click', deleteNode)
<div id="deleteDemo">
    <div>第一個子節點</div>
    
    <div>第三個子節點</div>
    <div>第四個子節點</div>
  </div>

2.replaceChild

parent.replaceChild(newNode,oldNode),將oldNode替換為newNode
dom如下

 <div id="replaceNodeDemo">
    <div>第一個子節點</div>
    <div>第二個子節點</div>
    <div>第三個子節點</div>
    <div>第四個子節點</div>
  </div>
  <input type="number" id="txtReplaceIndex" />
  <button id="btnReplace">替換一個孩子</button>

執行以下的js代碼,輸入一個數字,并點擊按鈕

function replaceNode() {
    var index = document.querySelector('#txtReplaceIndex').value
    var replaceNodeDemo = document.querySelector('#replaceNodeDemo')
    var children = replaceNodeDemo.querySelectorAll('div')
    var newNode = document.createElement('div')
    newNode.innerHTML = '我是替換之后的節點'
    var replaceChild = children[index] && replaceNodeDemo.replaceChild(newNode, children[index])
    console.log(replaceChild)
  }
  document.querySelector('#btnReplace').addEventListener('click', replaceNode)
<div id="replaceNodeDemo">
    <div>第一個子節點</div>
    <div>第二個子節點</div>
    <div>我是替換之后的節點</div>
    <div>第四個子節點</div>
  </div>

修改dom,一般是修改dom的屬性,dom的html, text, 表單的值等

1.setAttribute

A.setAttribute(property, value):設置屬性property的值為value
代碼

<div id="divSetAttribute"></div>
  <label for="txtProperty">屬性:</label>
  <input id="txtProperty" />
  <br />
  <label for="txtValue">屬性值:</label>
  <input id="txtValue" />
  <button id="btnProperty">設置屬性</button>
  <script type="text/javascript">
  var divSetAttribute = document.querySelector('#divSetAttribute')
  var txtProperty = document.querySelector('#txtProperty')
  var txtValue = document.querySelector('#txtValue')
  var btnProperty = document.querySelector('#btnProperty')

  function setAttribute() {
    divSetAttribute.setAttribute(txtProperty.value, txtValue.value)
  }
  btnProperty.addEventListener('click', setAttribute)
  </script>

2.innerHTML:獲取或者設置dom的dom內容

dom結構如下

  <div id="parent">
    <div>第一個子節點</div>
    <div>第二個子節點</div>
    <div>第三個子節點</div>
    <div>第四個子節點</div>
  </div>

獲取parent的innerHTML,結果為

   <div>第一個子節點</div>
   <div>第二個子節點</div>
   <div>第三個子節點</div>
   <div>第四個子節點</div>

3.innerText:獲取或者設置dom的文本內容

dom結構如下

  <div id="parent">
    <div>第一個子節點</div>
    <div>第二個子節點</div>
    <div>第三個子節點</div>
    <div>第四個子節點</div>
  </div>

獲取parent的innerText,結果為

第一個子節點
第二個子節點
第三個子節點
第四個子節點

注意與innerHTML的區別

4.value:獲取或者設置input, select的value

  <select id="s1">
    <option value="2">中國</option>
    <option  selected="true" value=3>日本</option>
    <option value="4">韓國</option>
  </select>
<script>
document.querySelector('#s1').querySelectorAll('option')[document.querySelector('#s1').selectedIndex].value
</script>

查詢dom,這一塊的api比較豐富,可能會有遺漏
1.document.getElementById(id):古老的方法,根據id獲取元素,不推薦
2.document.getElementsByTagName(tagName):古老的方法,根據dom的類型獲取元素,不推薦
3.document.getElementsByClassName(className):古老的方法,根據className獲取元素,不推薦
document.getElementsByName(name):古老的方法,根據name獲取元素,不推薦
4.document.getElementsByTagNameNS():沒用過

----------------------------------------------分割線----------------------------------------------
接下來,要重點介紹幾個目前常用的api

1.document.querySelector(css選擇器):根據css選擇器來獲取dom,如果有多個,返回第一個

dom

  <div class="test">1</div>
  <div class="test">2</div>
  <div class="test">3</div>

執行以下代碼

document.querySelector('.test')

返回

<div class="test">1</div>

2.document.querySelectorAll(css選擇器):返回所有滿足條件的元素

以上面的例子為例,如果使用querySelectorAll,那么返回值就是三個元素,這兩個api比較相似,只是一個返回一個dom,一個返回多個dom,不展開了

3.獲取子節點children

dom代碼

    <div id="div1">
        It's me
        <span>child</span>
        <div>
            child2
            <p>leaf</p>
        </div>
    </div>

執行以下代碼之后

document.querySelector('#div1').children

得到了兩個節點,分別是

<span>child</span>

<div>
     child2
     <p>leaf</p>
</div>

由此可見,children獲取的是dom元素

4.獲取所有子節點childNodes

還是上面的dom結構,來執行以下以下代碼

document.querySelector('#div1').childNodes

返回了五個元素

nodes[0] =It's me
nodes[1] =<span>child</span>
nodes[2] =換行符
nodes[3] =<div>
            child2
            <p>leaf</p>
        </div>
nodes[4] =換行符

很明顯,它不僅返回了dom子元素,還返回了文本子元素

5.獲取父節點parentNode和parentElement

兩者大體差不多,區別和children和childNodes類似,不贅述了

6.獲取兄弟節點previousSibling、previousElementSibling、nextSibling、nextElementSibling

推薦使用帶Element的,大多數情況下,好像都不需要文本節點

7.獲取首尾節點firstChild、firstElementChild、lastChild、lastElementChild

區別參考上一條

8.getComputedStyle

該方法是window下的一個方法,用來計算一個dom元素生成好之后的style,很全,不過因為chrome下的調試很方便,很少用到這個方法

9.getBoundingClientRect

這個方法我經常用到,在以前的博文中也有提到,它是用來獲取邊距的,很有用


屬性操作

1.setAttribute:設置dom的屬性

A.setAttribute(name,value),上面有提到,不贅述

2.getAttribute:得到dom的屬性

A.getAttribute('id') 獲取dom A的屬性id

3.removeAttribute移除屬性

A.removeAttribute(id) 移除id屬性


事件

1.添加事件:事件的添加,一般三種方式,直接綁定dom,通過js賦值,通過addEventListener

代碼

 <div id="div1" onclick="alert(1)">
    我是用來測試的
  </div>
  <script type="text/javascript">
  var div1 = document.querySelector('#div1')
  div1.onclick = function() {
    alert(2)
  }
  div1.addEventListener('click', function() {
    alert(3)
  })
  </script>

以上代碼分別通過三種方式綁定了事件,點擊的結果是,彈出了2和3,并沒有彈出1,這是因為,當js中直接給onclick賦值時,把直接綁定在dom上的事件覆蓋了,假如下面還有一個onclick的賦值,那么它也會覆蓋alert(2),但是add這種方式并不會覆蓋,而是會追加,我們再把代碼修改一下驗證

  <div id="div1" onclick="alert(1)">
    我是用來測試的
  </div>
  <script type="text/javascript">
  var div1 = document.querySelector('#div1')
  div1.onclick = function() {
    alert(2)
  }
  div1.onclick = function() {
    alert('2和3之間')
  }
  div1.addEventListener('click', function() {
    alert(3)
  })
  div1.addEventListener('click', function() {
    alert(4)
  })
  </script>

修改之后,彈出的結果是‘2和3之間’,3,4,由此可見,以上結論正確

2.移除事件

對于直接綁定在dom上的事件,可以采用removeAttribute來移除
對于賦值on這種的,可以重新賦值為null
對于add的,這種稍微復雜一點,此時首先在add時,不能直接綁定匿名方法 了,要定義一個具名的方法,移除時也要綁定上此方法,代碼如下

  <div id="div1">
    我是用來測試的
  </div>
  <script type="text/javascript">
  var div1=document.querySelector('#div1')
  function Test(){
    alert(133)
    div1.removeEventListener('click',Test)
  }
  div1.addEventListener('click',Test)
  </script>

以上點擊事件,只會執行一次

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容