HTML语义化:HTML5新标签——template

一、前言                              

  当我们使用String-base的模板引擎(如Handlebars.js等)时,要么就通过外部文件存放模板文本,需要时再通过XHR或script标签加载进来;要么通过等标签直接写在当前页面上。现在HTML5为我们提供了一个全新的template标签,以更统一、有效的方式存放String-base模板引擎的模板文本了!

  目录一坨:

  二、那些年我们存放模板文本的方式

    1. script标签

        2. textarea标签

        3. xmp标签

  三、template标签的新视觉

     1. 不一样的childNodes

   2. 伪文档片段入口——content属性

 

二、那些年我们存放模板文本的方式                  

  首先要明确模板文档具有以下2个要求:

    1.  <> "' 不被转成字符实体;

    2. 含src特性的img标签不触发资源请求。

  下面是常用的存放方式:

    1. script标签

// 模板文本


// 获取模板

   注意:

     1. 若模板中包含标签会造成标签结束符混乱的问题,因此通过该方式存放模板时,不能包含结束标签;

     2. script标签位置较随意,可以作为head或body的子元素。

 2. textarea标签

// 模板文本


// 获取模板

    注意:

  1. 若模板中包含标签会造成标签结束符混乱的问题,因此通过该方式存放模板时,不能包含结束标签;

  2. textarea元素必须作为body的子孙元素。

    3. xmp标签(语义为标识内容用作示例,现已被标准废除了,但各大浏览器依然支持该标签)

// 模板文本
"</span><span style="color: rgba(128, 0, 0, 1)">tpl</span><span style="color: rgba(128, 0, 0, 1)">"</span> style=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">display:none;</span><span style="color: rgba(128, 0, 0, 1)">"</span>>
<img src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dummy.png</span><span style="color: rgba(128, 0, 0, 1)">"</span> title=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{title}}</span><span style="color: rgba(128, 0, 0, 1)">"</span>/>


// 获取模板

    注意:

  1. 若模板中包含标签会造成标签结束符混乱的问题,因此通过该方式存放模板时,不能包含结束标签;

  2. xmp元素必须作为body的子孙元素。

  由于模板文本中出现

   注意:

     1. 若模板中包含标签会造成标签结束符混乱的问题,因此通过该方式存放模板时,不能包含结束标签;

     2. script标签位置较随意,可以作为head或body的子元素。

   到这里大家会觉得template标签除了作为W3C标准外,跟script标签没多大的差别。那是因为我们还没对其深入而已啦,下面我们将对其一一了解吧!

   1. 不一样的childNodes

     script、textarea和xmp方式存放模板文本时,通过 tplEl.childNodes.length 均返回1, tplEl.childNodes[0].nodeName 均返回#text。而template返回的是0。

   2. 伪文档片段入口——content属性

     通过innerHTML或innerText属性,template内部的模板文本将被视为普通文本来使用。但template元素为我们提供了另一种使用方式,那就是“文档片段”。

     “文档片段”的[[Class]]为[object DocumentFragment],“文档片段”具有文档片段的所有功能API,不同的是设置img元素的src属性不会发出资源请求、不执行Script和CSS规则,而[object HTMLDocument]“文档”则会发送img请求并在当前browsing context(即window对象上下文)内执行Script和CSS规则。

而我们可以通过content属性获取“文档片段”。

var tplEl = document.getElementById('tpl')
var x = tplEl.content
var img = x.querySelector('img')
console.log(img.src) // 显示空字符串
console.log(img.getAttribute('src')) // 显示dummy.png
img.src = img.getAttribute('src')
console.log(img.src) // 显示about:blank

    当添加到当前文档中才会发起资源请求。

document.body.appendChild(img)
// 发起资源请求
console.log(tplEl.innerHTML.replace(/^[\s\u3000]*|[\s\u3000]*$/,'')) // 显示空白字符串

    由于appendChild方法实际上会对元素进行剪切操作,因此无法实现模板复用的效果。因此我们需要复制模板内的元素,然后再将元素副本添加到当前文档中。实现手段有很多种,大家可以自行了解一下。

    那么怎样将整个template提供的DocumentFragment导出到当前document呢?答案就是采用IE9+才有的document.importNode方法了。

var tplEl = document.getElementById('tpl')
var x = tplEl.content
var clone = document.importNode(x, true)
document.body.appendChild(x)

 

四、总结                              

  本篇为拜读张鑫旭《HTML5