HTML5 template元素
前言
轉自http://www.zhangxinxu.com/wordpress/2014/07/hello-html5-template-tag/
在單頁面應用,我們對頁面的無刷新有了更高的要求,HTML不再由後端生成,後端只提供一個REST API,返回JSON數據,模版引擎可以大大方便我們渲染一個視圖。而不是吃力的使用 jQeury 去拼接一個DOM。
在現在比較常見的 JS MVC Framework : backbone, emberjs, angularjs 中,模板是非常重要的一個組件。
首先要明確模板文檔具有以下2個要求:
1. <> "‘ 不被轉成字符實體;
2. 含src特性的img標簽不觸發資源請求。
一、HTML5 template元素初面
<template>
元素,基本上可以確定是2013年才出現的。幹嘛用的呢,顧名思意,就是用來聲明是“模板元素”。
目前,我們在HTML中嵌入模板HTML,往往是類似這樣的寫法:
<script type="text/template">
// ...
</script>
實際上,並不存在type="text/template"
這樣的標準寫法,<template>
元素的出現旨在讓HTML模板HTML變得更加標準與規範。
以前,我們可能還使用過<textarea>
<xmp>
(廢止但依然可用)嵌套非轉義的HTML標簽代碼,實現一些特定的前端功能,但,同樣的,跟上面的流行用法一樣,都是不規範的。從未來趨勢來講,顯然<template>
標簽才是王道。但是,兼容性是個不可忽略的問題,因此,就算扯得很多很少,實際價值有有限,因此,這裏僅僅簡單介紹下。
二、HTML5 template元素復面
看下下面四種嵌套圖片HTML,同時圖片內容不顯示,不會有請求的寫法:
<script type="text/template">
<img src="mm1.jpg">
</script>
<textarea style="display: none;"> <img src="mm1.jpg"> </textarea>
<xmp style="display: none;">
<img src="mm1.jpg">
</xmp>
<template>
<img src="mm1.jpg">
</template>
1. 標簽內容隱藏性
<script>
本身的特定,讓內部的HTML標簽是按照字符串處理的,因此,天生內容不顯示。但是,在DreamWeaver中,這種寫法有個很大的問題,就是在script
中書寫模板HTML時候,標簽自動閉合的永遠是</script>
這個很討厭的。<textarea>
為文本域,裏面嵌套的HTML片段會被當做文本域的值。但,文本域本身是可見的,因此需要額外的設置display: none;
<xmp>
是個很老很特殊的屬性,語義為example
,示例。據說後來被<pre>
標簽取代而廢止,實際上,目前,所有的瀏覽器都是支持的。但是,其跟<pre>
標簽不能劃等號。<pre>
裏面有個<img>
標簽,顯示的則是一張圖片,而<xmp>
呈現的就是一段HTML代碼。不過,與<textarea>
一樣,內容不顯示的話,還需要額外的設置display: none;
- 上面這個
<template>
標簽上沒有設置display: none;
,註意到了沒有。為何?這只是發揮了<template>
標簽元素的原本特性,天生display:none
,同時模板元素內部內容是死活不會呈現的。因此,無需設置隱藏。
2. 標簽位置任意性
除了上面<template>
子元素天然隱藏外,<template>
標簽還有一個特性,就是位置任意性,這非常類似<script>
或者<style>
標簽,可以在<head>
中,也可以在<body>
或者<frameset>
中。
3. childNodes無效性
雖然,肉眼看上去是<template>
標簽裏面還有很多子標簽,這種慣性思維在這裏是不受用的。假設變量template
是我們獲得的一個<template>
標簽DOM(裏面一大堆HTML代碼),你會發現:template.childNodes
是個空大屁。我們可以使用template.innerHTML
獲取完整的HTML片段。如果你非得獲取“偽子元素”。也是有辦法的,OK,睜大眼睛,要使用content
屬性。
template.content
會返回一個文檔片段,你可以理解為另外一個document
,然後,使用document
下的一些查詢API就可以獲得<template>
標簽裏面的“偽子元素”了。例如,獲得第一張圖片元素則是:
var image_first = template.content.querySelector("img");
三、HTML5 template元素終面
模板元素與CSS
如果瀏覽器有眼不識泰山,認為<template>
就是個普通的自定義元素,則顯示的就會使下面這個樣子,內部的標簽按照一般的標簽渲染了,例如IE11:
如果瀏覽器與時俱進,則顯示會是下面這樣,自身CSS渲染,內部標簽直接異空間不渲染,例如Chrome:
也就是說,雖然從CSS的角度看,<template>
就是個跟CSS打得火熱的普通元素,但是,從HTML角度看,其猶如帶土的寫輪眼,可以讓內部標簽轉移到異空間,血跡界限般稀有。
默認情況下,<template>
是隱藏的,實際是默認其display
屬性為none
. 使用下面的代碼一測便知:
window.getComputedStyle(template).display; // 結果是"none"
因此,demo中才設置了如下的CSS聲明:
template { display: block; ... }
模板的克隆
如果你是在HTML字符串上處理,類似於現在流行的MVC框架或模板技術,則template.innerHTML
足矣。然,<template>
比<script>
強大之處在於,<script>
內部內容只能當做字符串來獲取,而<template>
雖然存在於異空間,但是,依然可以節點獲取(上面有展示),以及完整克隆,語法類似下面:
var clone = document.importNode(template.content, true);
然後,你就可以用append節點(appendChild)的方式,加載模板內容了,而不是(沒得選擇)append字符串加載模板內容。
HTML5 template元素