HOWTO · JavaScript
使用 JavaScript 將 HTML 內容附加到現有的 HTML 元素
本教程詳細介紹瞭如何使用 JavaScript 附加 HTML。
本頁內容
若要在既有元素中加入內容,請依照手上的內容選擇 API:使用 appendChild() 加入 DOM 節點,或使用 insertAdjacentHTML() 在指定位置解析並插入 HTML 字串。設定 innerHTML 會取代元素的後代節點,因此不適合用來保留既有子元素。
使用 innerHTML 新增 HTML 節點的缺點
設定元素的 innerHTML 時,瀏覽器會解析指定的字串,並取代該元素的後代節點。這可能會捨棄那些節點所保有的狀態,以及直接綁定在節點上的事件監聽器。這不代表目標元素的所有屬性都會被移除:目標元素本身仍會保留,只有它的子節點會被取代。
innerHTML 和 insertAdjacentHTML() 都會將字串解析為標記。若字串包含不受信任的輸入,就可能造成跨網站指令碼(XSS)風險。建議建立節點,並透過 textContent 這類文字屬性設定使用者提供的值;若必須插入標記,請使用適合該應用程式的方式進行消毒。請參閱 MDN 的 innerHTML 安全性注意事項。
新增 HTML 內容而不取代 DOM 元素
若要加入新建的元素,請建立節點並將它插入既有的 DOM 樹。若要加入可信任的 HTML 字串,請使用 insertAdjacentHTML() 並選擇插入位置。這兩種做法都能新增內容,而不會取代目標元素原有的後代節點。以下範例使用簡單的地址表單,示範這兩種做法。
在 JavaScript 中使用 appendChild() 附加 HTML 內容
appendChild() 接受的是節點,而不是 HTML 字串。它會將節點放在目標目前最後一個子節點之後。若該節點已位於文件的其他位置,附加時會移動同一個節點,而不是建立副本。
執行此範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
function addAddressLine(addressContainer, lineCount) {
const input = document.createElement("input");
input.type = "text";
input.placeholder = `Address Line ${lineCount}`;
addressContainer.appendChild(input);
}
if (typeof document !== "undefined") {
let lineCount = 0;
const button = document.getElementById("add-address");
const addressContainer = document.getElementById("address");
button.addEventListener("click", () => {
addAddressLine(addressContainer, ++lineCount);
});
}
請將指令碼放在此表單之後,或使用 defer 載入,確保指令碼查找表單元素前,它們已經存在:
<form>
<label>Name: <input id="name" type="text"></label>
<div id="address">
<label>Address: <input id="contact" type="text"></label>
</div>
<button id="add-address" type="button">Add Address Line</button>
</form>
點擊事件處理函式會遞增地址行號,並將新的文字輸入欄位附加到 address 元素。原有的姓名和地址欄位會保留。type="button" 屬性可避免按鈕送出表單。
注意
append() 也是一種選擇:它接受節點和字串文字,但字串引數會以文字插入,而不會解析為 HTML。若需要使用它回傳的節點,或程式需要使用既有的單一節點操作,請選用 appendChild()。此處不討論瀏覽器支援情況;若應用程式有特定需求,請確認目標瀏覽器是否支援。
使用 insertAdjacentHTML() 在指定位置插入 HTML
呼叫 target.insertAdjacentHTML(position, htmlString),即可解析字串,並將產生的標記插入 target 的相對位置:
beforebegin會將內容插在目標元素正前方。目標元素必須有父元素。afterbegin會將內容插入目標元素內,位於第一個子節點之前。beforeend會將內容插入目標元素內,位於最後一個子節點之後。附加標記時會使用這個位置。afterend會將內容插在目標元素正後方。目標元素必須有父元素。
例如,以下程式會在地址容器的尾端插入新的地址輸入欄位:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
if (typeof document !== "undefined") {
const addressContainer = document.getElementById("address");
addressContainer.insertAdjacentHTML(
"beforeend",
'<input type="text" placeholder="Additional address line">'
);
}
與 appendChild() 不同,此方法會將第二個引數解析為 HTML。只有在字串可信任或已安全消毒時才使用;請勿將不受信任的文字串接到標記中。若內容來自使用者輸入,請建立元素並設定其 textContent 或其他適當屬性,再附加該節點。