js中Dom操作的個人總結

weixin_34116110發表於2018-01-07

一 js中的Dom操作處理

一 獲取元素

  • querySelector的效能會比get系列的要高,因為返回的是nodeList的快照。
  • querySelector獲取的是快照,所以當元素更新的時候,獲取的快照不會更新。
  • querySelector系列是靜態的,get系列是動態的。
  • 其中,document.getElementById('mybtn')只有document才有
document.querySelector('.mybtn')   /// 返回第一個與選擇器匹配的元素
document.querySelectorAll('.mybtn')  // 返回所有與選擇器匹配的元素
document.getElementsByClassName('mybtn')   // 返回所有className 為mybtn的元素
document.getElementsByTagName('div')
document.getElementById('mybtn')
document.getElementByName('mybtn')  // 可以通過name獲取表單(表單的id與label的for要保持一致。)
document.getElementByTagName('*') // 可以獲取頁面中所有的元素

轉載自知乎的一個demo,

因為 Demo 2 中的 lis 是一個動態的 Node List, 每一次呼叫 lis 都會重新對文件進行查詢,導致無限迴圈的問題。而 Demo 1 中的 lis 是一個靜態的 Node List,是一個 li 集合的快照,對文件的任何操作都不會對其產生影響。

作者:簡生
連結:https://www.zhihu.com/question/24702250/answer/28695133
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

// Demo 1
var ul = document.querySelectorAll('ul')[0],
    lis = ul.querySelectorAll("li");
for(var i = 0; i < lis.length ; i++){
    ul.appendChild(document.createElement("li"));
}

// Demo 2
var ul = document.getElementsByTagName('ul')[0], 
    lis = ul.getElementsByTagName("li"); 
for(var i = 0; i < lis.length ; i++){
    ul.appendChild(document.createElement("li")); 
}

作者:簡生
連結:https://www.zhihu.com/question/24702250/answer/28695133
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

二 增刪class,使用classList

  • element.classList.add增加class
  • element.classList.remove刪除class
  • element.classList.containes是否包含class,返回true或者false
  • element.classList.toggle切換class
  • div.classList.replace("foo", "bar"); 替換class
三 直接修改整個class ,使用className
  • ele.className = 'foo goo do '設定ele的class,也可以用這個屬性去獲取ele的class
let elm = document.getElementById('item');

if(elm.className === 'active'){
    elm.className = 'inactive';
} else {
    elm.className = 'active';
}

四 自定義資料屬性

  • data-set,獲取自定義屬性的方法,ele.dataset.name
  • 主要用在跟蹤連線上會有用處,可以設定相應的自定義屬性,進行跟蹤連線。
<div id="myDiv" data-name="myDiv" data-id="myId"
       data-my-custom-key="This is the value"></div>

// 獲取的方法
ele.dataset.name 
ele.dataset.myCustomKey
ele.dataset.id

// 也可以直接定義
ele.dataset.name  = ‘katherine’
ele.dataset.myCustomKey = ‘new value’
ele.dataset.id = 'newID'

五 獲取dom元素的屬性的方法,獲取某一個屬性atrr的方法有哪些呢?

  • ele.attr 設定獲取獲取元素的屬性,但是不能設定或者獲取自定義屬性
  • getAttribute(attr) setAttribute(attr,'new'),的方法獲取或者設定屬性

這兩種方法的比較和對比

  • ele.attr 不能設定或者獲取自定義屬性,使用getAttribute相關方法則可以設定或者獲取自定義屬性。
  • 當使用ele.style 得到的是一個style的物件值,所以可以通過ele.style.color獲得某一個樣式的值;而使用getAttribute 相關方法獲取的style是字串。
  • 使用ele.attri獲取class的時候,是使用ele.className.而使用getAttribute方法的時候,是直接使用ele.getAttribute('class')
<div id="myDiv" data-name="myDiv" data-id="myId" class='test'
       data-my-custom-key="This is the value"></div>

var Odiv = document.getElementById('myDiv');
// 
Odiv.id   //myDiv
Odiv.className // test


//
Odiv.getAttribute('id')  // myDiv
Odiv.getAttribute('class')  .. //test
Odiv.getAttribute('data-name')   // myDiv

六 使用ele.tagName的時候要注意

  • 使用ele.tagName會返回該元素的標籤名,但是要比較的話,最好是用ele.tagName.toLowerCase === 'div'去比較和使用最好。

七 節點與元素節點

傳統的獲取不同的節點的方法有如下
  • ele.childNodes // 返回某一個元素的所有子節點,包括文字節點
  • ele.previousSibling // 返回同級的前面的兄弟元素
  • ele.nextSibling // 返回同級的後面的兄弟元素
  • ele.firstChild // 返回第一個子元素
  • ele.lastChild //返回最後一個子元素
新的不包含文字節點的獲取元素節點的方法,不包含空元素節點和文字節點
  • ele.childElementCount // 返回某一個元素的所有子節點的個數
  • ele.previousElementSibling // 返回同級的前面的兄弟元素
  • ele.nextElementSibling // 返回同級的後面的兄弟元素
  • ele.firstElementChild // 返回第一個子元素
  • ele.lastElementChild //返回最後一個子元素

七 設定和獲取 innerHTML innerText

相比於建立節點,再將節點append或者穿插到某一個節點處,innerHTML還是比較高效率的。

  • 當設定了一個元素的innerHTML和innerText之後,之前的內部元素都會被清除,重新覆蓋。
  • 使用innerHTML的時候,要注意儘量減少使用的次數,因為頻繁使用innerHTML會造成效能問題。
下面的例子就是,儘量少用innerHTML
for (var i = 0; i < length; i++) {
 ul.innerHTML += "<li>" + values[i] + "</li>"; 
}
// 高效率的做法應該是這樣子
var newHtml = ''
for (var i = 0; i < length; i++) {
 newHtml += "<li>" + values[i] + "</li>"; 
}
ul.innerHTML = newHtml;
八 建立以及插入節點的相關方法。

✔注意: 如果使用appendChild的時候,插入的元素已經是文件的節點,那麼這個文件的節點就會從原來的位置偏移到新的位置去,即文件中的任何節點都不能同時出現在兩個位置。

document.createElement('div')   //建立一個div的節點。
father.appendChild(newNode)   //在father節點的最後新增new節點
father.insertBefore(newNode,father.firstChild)  // 將newnode插入到father的第一個子元素之前

相關文章