innerHTML 的寫法
前面已經學過了用 textContent 在 HTML 中插入文字了,現在要來學習如何用 innerHTML 插入內容。欲插入的內容必須是字串型別,而且內容要包含 HTML 標籤。
如果插入的內容包含 class 屬性,要小心包圍 class 值的單雙引號不要跟外面包起來的引號重複,不然解譯器不知道這一行程式碼的終點到哪。
var el = document.getElementById('main');
el.innerHTML = '1234'
注意:如果本來 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 = '' + name + '';
小撇步:在要替代成變數的位置先打上「'++'」,然後把變數填入兩個加號中間。不過組字串這個惱人的差事,在 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);
★ 補充
將父元素宣告變數,程式碼會比較簡潔
想要掛上子節點的父元素,可以先用變數儲存好它的 DOM 節點(用 querySelector()),這樣之後就可以直接寫:父元素變數.appendChild(子節點變數) 了,程式碼簡潔很多。
用這個方法增加文字,不需要先宣告一個空字串來儲存
因為 appendChild() 本身就帶有累加的功能了。
XSS(cross-site scripting)跨站指令攻擊
當我們的網頁有允許使用者輸入文字的欄位,而且剛好又搭配使用 innerHTML 的話,很容易被駭客植入一些惡意的程式碼。
innerHTML vs. createElement
最後快速比較兩種方法的差異:
innerHTML
方法:組完字串後,傳進 HTML 裡進行渲染
優點:效能高
缺點:有資安風險,要確保傳進 HTML 的程式碼來源沒問題
createElement
方法:以建立一個新的 DOM 節點來處理
優點:安全性高
缺點:效能差
小結
innerHTML 較適合用於變更整個 DOM 樹分支,而 DOM 控制處理則是針對每個節點進行處理。