今天這篇文章要介紹兩種在 DOM 樹中增加內容的方法,分別為 innerHTML
特性和 DOM 控制處理(createElement()
+ appendChild()
)。
前面已經學過了用 textContent
在 HTML 中插入文字了,現在要來學習如何用 innerHTML
插入內容。欲插入的內容必須是字串型別,而且內容要包含 HTML 標籤。
如果插入的內容包含 class 屬性,要小心包圍 class
值的單雙引號不要跟外面包起來的引號重複,不然解譯器不知道這一行程式碼的終點到哪。
var el = document.getElementById('main');
el.innerHTML = '<h1 class="blue">1234</h1>'
注意:如果本來 HTML 某元素有既有的內容,但是又用 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 裡有更好的寫法,礙於篇幅現在先不講。
需要搭配 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);
★ 補充
querySelector()
),這樣之後就可以直接寫:父元素變數.appendChild(子節點變數)
了,程式碼簡潔很多。appendChild()
本身就帶有累加的功能了。當我們的網頁有允許使用者輸入文字的欄位,而且剛好又搭配使用 innerHTML
的話,很容易被駭客植入一些惡意的程式碼。
最後快速比較兩種方法的差異:
方法:組完字串後,傳進 HTML 裡進行渲染
優點:效能高
缺點:有資安風險,要確保傳進 HTML 的程式碼來源沒問題
方法:以建立一個新的 DOM 節點來處理
優點:安全性高
缺點:效能差
innerHTML
較適合用於變更整個 DOM 樹分支,而 DOM 控制處理則是針對每個節點進行處理。
不好意思,針對本篇文章最後的小結,我有點看不太懂意思,能否請你再說明一下。尤其是「而 DOM 控制處理則是針對每個節點進行處理。」這句話。
另外從整篇文章讀下來,我看的感覺是 creatElement 較適合用於變更整個 DOM 樹分支。
ps. 我快要看完了,謝謝你的文章,簡潔有力、清晰易懂,謝謝!
哈哈,我剛剛又重看了一邊,我知道「而 DOM 控制處理則是針對每個節點進行處理。」這句話的意思了。
對不起。