iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
3
Modern Web

JavaScript 初心者筆記系列 第 20

JavaScript 初心者筆記: DOM - 如何用 JS 新增 HTML 內容

  • 分享至 

  • xImage
  •  

今天這篇文章要介紹兩種在 DOM 樹中增加內容的方法,分別為 innerHTML 特性和 DOM 控制處理(createElement() + appendChild())。


innerHTML 的寫法

前面已經學過了用 textContent 在 HTML 中插入文字了,現在要來學習如何用 innerHTML 插入內容。欲插入的內容必須是字串型別,而且內容要包含 HTML 標籤。
如果插入的內容包含 class 屬性,要小心包圍 class 值的單雙引號不要跟外面包起來的引號重複,不然解譯器不知道這一行程式碼的終點到哪。

var el = document.getElementById('main');
el.innerHTML = '<h1 class="blue">1234</h1>'

注意:如果本來 HTML 某元素有既有的內容,但是又用 innerHTML 在同樣的元素上加上內容的時候,innerHTML 會把原本寫的東西覆蓋掉。

innerHTML 跟字串的組合

這個部分最複雜的應該是單引號、雙引號的辨認吧……。
假如我要用 innerHTML 插入一個 a 連結,且同時要插入連結網址跟連結文字:

// 選取 DOM:欲插入 a 連結的 DOM 名為 .list
var el = document.querySelector('.list');
// 欲插入的連結網址
var link = 'http://www.google.com.tw';
var name = '卡斯伯';
el.innerHTML = '<li><a href="' + link + '">' + name + '</a></li>';

小撇步:在要替代成變數的位置先打上「'++'」,然後把變數填入兩個加號中間。不過組字串這個惱人的差事,在 ES6 裡有更好的寫法,礙於篇幅現在先不講。

createElement 的寫法

需要搭配 appendChild() 語法使用,在 HTML 父元素下新增子元素。
innerHTML 的不同在於,innerHTML 會覆蓋掉原本的內容,而 createElement 會保留原本內容,依序加在後面。

// 用 createElement 增加一個 DOM 節點
var str = document.createElement('em');
// 先用 JS 寫好要增加的內容
str.textContent = '1234';
// 動態掛一個 class 屬性
str.setAttribute('class','blue');
// 用 appendChild() 把上面寫好的子節點掛在既有的 h1 下面,新增的內容會依序排列在後面,不會被洗掉
document.querySelector('.title').appendChild(str);

★ 補充

  1. 將父元素宣告變數,程式碼會比較簡潔
    想要掛上子節點的父元素,可以先用變數儲存好它的 DOM 節點(用 querySelector()),這樣之後就可以直接寫:父元素變數.appendChild(子節點變數) 了,程式碼簡潔很多。
  2. 用這個方法增加文字,不需要先宣告一個空字串來儲存
    因為 appendChild() 本身就帶有累加的功能了。

XSS(cross-site scripting)跨站指令攻擊

當我們的網頁有允許使用者輸入文字的欄位,而且剛好又搭配使用 innerHTML 的話,很容易被駭客植入一些惡意的程式碼。

innerHTML vs. createElement

最後快速比較兩種方法的差異:

innerHTML

方法:組完字串後,傳進 HTML 裡進行渲染
優點:效能高
缺點:有資安風險,要確保傳進 HTML 的程式碼來源沒問題

createElement

方法:以建立一個新的 DOM 節點來處理
優點:安全性高
缺點:效能差

小結

innerHTML 較適合用於變更整個 DOM 樹分支,而 DOM 控制處理則是針對每個節點進行處理。


上一篇
JavaScript 初心者筆記: DOM - 如何用 JS 更改 HTML & CSS 屬性
下一篇
JavaScript 初心者筆記: 應用 innerHTML 與 for 迴圈將資料渲染至網頁
系列文
JavaScript 初心者筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
maxtsou
iT邦新手 5 級 ‧ 2020-12-19 08:24:38

不好意思,針對本篇文章最後的小結,我有點看不太懂意思,能否請你再說明一下。尤其是「而 DOM 控制處理則是針對每個節點進行處理。」這句話。

另外從整篇文章讀下來,我看的感覺是 creatElement 較適合用於變更整個 DOM 樹分支。

ps. 我快要看完了,謝謝你的文章,簡潔有力、清晰易懂,謝謝!

maxtsou iT邦新手 5 級 ‧ 2020-12-19 08:28:08 檢舉

哈哈,我剛剛又重看了一邊,我知道「而 DOM 控制處理則是針對每個節點進行處理。」這句話的意思了。

對不起。

我要留言

立即登入留言