JavaScript 小學 — Dom 節點操作
先知道什麼是 Dom 吧!
DOM (Document Object Model,文件物件模型),是一個像樹狀圖一樣的文件結構,方便查看存取樹中的節點來改變其結構、樣式(CSS)或內容等,他的最起始點是就是 window.document
,然後再延伸出 html
> head
、 body
....可以叫做 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的方法:
- innerHTML:直接組成字串,進行語法渲染
- 優點:效能快。
- 缺點:資安風險高,容易被植入程式碼。
2. CreateElement:以 dom 節點來處理
- 優點:安全性高
- 缺點:比較耗效能
如何用innerHTML?
- 先定位一個你要在HTML中置入的位置,可以使用上面說到的任一方法,我用
.querySelector('.main')
來定位一個叫 main 的元素。 - 再透過 DOM Element Object.innerHTML 屬性在指定元素置入所有的內容。
el=document.querySelector('.main');
el.innerHTML='<h1 class="color-blue">Hello world</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>';
或是跟 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。
.createElement()
.createElement() 是先製作好元素,再把它塞在 html 的特定位置中,例如:
<h1 class="title"></h1>
怎麼塞呢?就是使用 .appendChild()
,增加一個子節點,就是掛一個小孩給你拉!!
let strCE=document.createElement('em');
strCE.textContent='createElement-1234';
document.querySelector('.main').appendChild(strCE);
最後如果想要為這個元素加上 css,就可以用 setAttribute():
let strCE=document.createElement('em');
strCE.textContent='createElement-1234';
strCE.setAttribute('class','color-blue');
document.querySelector('.main').appendChild(strCE);
可以利用下面的 codepen 改變看看: