JavaScript 小學 — Dom 節點操作

Jordan Tseng
JordanTTCDesign
Published in
11 min readDec 11, 2020

先知道什麼是 Dom 吧!

DOM (Document Object Model,文件物件模型),是一個像樹狀圖一樣的文件結構,方便查看存取樹中的節點來改變其結構、樣式(CSS)或內容等,他的最起始點是就是 window.document ,然後再延伸出 html > headbody ....可以叫做 DOM Tree 。

我們了解這個的目的就是為了透過 js 取出 document 中的各種元素節點~

操作 DOM 元素的常見方法

我們先介紹三種取得 dom 元素的語法:

  • .getElementById()
  • .getElementsByClassName()
  • .querySelector()
  • .querySelectorAll()
// 找到 DOM 中 具備 id 為 'hello' 的元素。
document.getElementById("hello");
// 找到 DOM 中 具備 class 為 'hello' 的元素。
document.getElementsByClassName("hello");
// 針對給定的 Selector 條件,回傳第一個 或 所有符合條件的元素。
document.querySelector(".hello");
document.querySelectorAll(".hello");

.getElementById() 根據id拿元素

顧名思義就是從 dom 中找到一個 id 名稱跟 () 內容一樣的元素。

<h1 id="pageTitle">hello</h1>
<a id="logo"></a>

HTML 裡面有一個 id 是 pageTitle ,另外一個是logo

var pageTitle=document.getElementById("pageTitle");
console.log(pageTitle.textContent)//hello

上面用到的 .textContent 就是該元素的內容,所以代表如要改變顯示內容,我們就可以寫:

var pageTitle=document.getElementById("pageTitle");
pageTitle.textContent='改摟~';

.getElementsByClassName() 根據class拿元素

跟剛剛的 id 差不多,不同的是因為 class 可以有很多,所以他會把 dom 中所有具有該 class名稱的元素全部取出。

<p class="pageTitle">hello</p>
<p class="txt">hello</p>
<p class="txt">hello</p>
<p class="txt">hello</p>
<p class="txt">hello</p>

上面的 html 中有四個 class 是 txt,剛剛提到說抓出全部,所以他會存在陣列當中,那就要使用 for迴圈去操作摟~

var str=document.getElementsByClassName('txt')
var str=document.getElementsByClassName("txt");
for(let i =0 ;i<str.length;i++){
str[i].textContent="改摟~";
}

.getElementsByTagName() 根據標籤名選取元素

getElementsByTagName()方法可用來選取特定tag名稱的所有HTML或XML元素,並且也是跟class一樣會回傳陣列。

document.getElementsByTagName('span')  // 选取所有span元素

甚至也還有更多玩法,多一層,想取得特定 ul 裡面的 li

let ul = document.getElementsByTagName('ul')[1];
let span = ul.getElementsByTagName('li');

更方便的寫法querySelector

怎麼說更方便呢?因為我們一定都學過 css ,所以就直接沿用 css的class、id寫法即可,很淺顯易懂。如果要抓一個就是用 .querySelector(),注意這裏說的一個代表當 相同 class 有很多個,只會抓第一個喔~

<p class="pageTitle">hello</p>
<p class="txt">hello</p>
<p class="txt">hello</p>
<p id="spcialTxt">hello</p>
<p class="txt">hello</p>

*既然是 css 寫法,那 () 中就要加上 ("#")(id) 或(".")(class)。

var el=document.querySelector(".txt");
el.textContent="改摟~";

querySelectorAll()

如果用 querySelectorAll(),就是要抓全部的,那也會全部放到一個陣列中:

var el=document.querySelectorAll(".txt");
for(let i =0 ;i<str.length;i++){
el[i].textContent="改摟~";
}

這裡的抓出來並賦予值的變數其實是一個物件,我們可以針對這個物件去新增修改刪除他的屬性。

setAttribute() 新增修改屬性

setAttribute()的結構是,前面是屬性名稱、後面是設定值,要注意的是如果本身沒設定過那個屬性那便是新增,但如果有設定過了就是修改,因為他會直接整個覆蓋掉。EX:可以設定他的路徑

el=document.querySelector('.titleClass a');
el.setAttribute('href','<http://google.com>');

而我舉一個值被覆蓋掉的例子,我選了一個元素設定class名稱:

<p class="pageTitle">hello</p>
<p class="txt big">hello</p>
<p class="txt big">hello</p>
<p class="txt">hello</p>
<p class="txt big">hello</p>
str=document.querySelector('.txt');
str.setAttribute('class','blue');

結果因為我取出第一個class為txt的元素把他的class設定為 active,變成它沒有吃到big的css,因為blue 把它全部的 class 覆蓋掉了。

getAttribute()讀取屬性

修改是set,那讀取就是get,這其實滿常用的唷,像是可以取出該元素之路徑、文字內容或是特別幫自訂的屬性,可以用來跑各種程式用途。

strClass=document.querySelector('.titleClass').getAttribute('class');
console.log(strClass)//btn active

removeAttribute()刪除屬性

利用removeAttribute(),就可以把該屬性刪除,像下面的程式碼,就把class直接刪掉變成null。

var el=document.querySelector(".txt");
console.log(el.getAttribute('class'));//"txt active big"
el.removeAttribute('class','big');
console.log(el.getAttribute('class'));//null

用JS操作HTML

來學學兩個簡單的JS操作HTML的方法:

  1. innerHTML:直接組成字串,進行語法渲染
  • 優點:效能快。
  • 缺點:資安風險高,容易被植入程式碼。

2. CreateElement:以 dom 節點來處理

  • 優點:安全性高
  • 缺點:比較耗效能

如何用innerHTML?

  1. 先定位一個你要在HTML中置入的位置,可以使用上面說到的任一方法,我用.querySelector('.main') 來定位一個叫 main 的元素。
  2. 再透過 DOM Element Object.innerHTML 屬性在指定元素置入所有的內容。
el=document.querySelector('.main');
el.innerHTML='<h1 class="color-blue">Hello world</h1>'
innerHTML 插入一個 h1

*注意:如果這個指定HTML元素本身裡面有內容,當我們用了innerHTML(),本身的內容會被洗掉換成,innerHTML的內容。

我們還能加入變數到innerHTML中:

var el = document.querySelector('.list');
var link='<http://google.com>';
var name='Jack'
el.innerHTML='<li><a href="'+link+'">'+name+'</a></li>';
innerHTML 插入一個 li

或是跟 for 迴圈做結合:

var farms = [
{
worker: "Jordan",
salary: 88000
},
{
worker: "Zoe",
salary: 80000
},
{
worker: "Yui",
salary: 10000
},
];
let farmList = document.querySelector('.farmList');
let farmLen=farms.length;
let str='';
for(let i=0;i<farmLen;i++){
let content='<li>'+farms[i].worker+'</li>';
str+=content
}
farmList.innerHTML=str;
用迴圈 innerHTML 插入數個 li

但是因為他是最後置入一長段內容,所以要在每一次迴圈時,把當次產生的內容先塞到一個字串中,但把那個字串附值至innerHTML。

.createElement()

.createElement() 是先製作好元素,再把它塞在 html 的特定位置中,例如:

<h1 class="title"></h1>

怎麼塞呢?就是使用 .appendChild() ,增加一個子節點,就是掛一個小孩給你拉!!

let strCE=document.createElement('em');
strCE.textContent='createElement-1234';
document.querySelector('.main').appendChild(strCE);
.createElement(),插入一個元素到.main

最後如果想要為這個元素加上 css,就可以用 setAttribute():

let strCE=document.createElement('em');
strCE.textContent='createElement-1234';
strCE.setAttribute('class','color-blue');
document.querySelector('.main').appendChild(strCE);
把元素改成藍色

可以利用下面的 codepen 改變看看:

--

--