HTML <!–…–> 注释标签

从今天起,我会写一系列的 HTML 标签的文章,今天就从 <!--...--> 注释标签 开始讲起。

定义和用法

注释标签用于在源代码中插入注释,注释不会显示在浏览器中。

说明:尽可能的去解释你写的代码。用注释来解释代码:它包括什么,它的目的是什么,它能做什么,为什么使用这个解决方案,还是说只是因为偏爱如此呢?

<!--这是一段注释,但是注释不会在浏览器中显示。-->

<p>这是一段普通的段落。</p>

注释标签的作用

使用注释对代码进行解释,有助于在以后对代码进行编辑和维护。尤其在页面代码量大时候,给 HTML 代码添加注释是非常用必要的。

注释 HTML 代码

添加适当的注释,能有效的提高代码的可读性,更清晰的了解 HTML 代码的结构。

<!--新闻模块-->
<div class="news-module">
    <!--新闻模块标题栏-->
    <div class="news-module-hd">
         <!--新闻模块标题-->
         <h2 class="news-module-title">新闻</h2>
         <!--新闻模块标签导航-->
         <ul class="news-module-tabs">
             <li class="news-module-tab news-module-active-tab"><a href="#headline">头条</a></li>
             <li class="news-module-tab"><a href="#sports">体育</a></li>
             <li class="news-module-tab"><a href="#science">科技</a></li>
         </ul>
    </div>
    <!--新闻模块正文-->
    <div class="news-module-bd">
        <ul class="news-module-list">
            <li><a href="http://sports.163.com/17/1208/03/D53SHEOP00058781.html">金评梅和三票罗的年代,球迷谁能想到1-4变5-5?</a></li>
        </ul>
    </div>
    <!--新闻模块页脚-->
    <div class="news-module-fd"></div>
</div>

注释 JavaScript 代码

除了可以注释 HTML 代码,针对旧版本的浏览器,我们会在 <script> 标签中添加注释的方式,为不支持 JavaScript 的浏览器隐藏掉 JavaScript 代码。例如:

<script type="text/javascript">
<!--
function sayHello(){
    alert("Hello World!")
}
//-->
</script>

说明:注释行结尾处的双斜杠 (//) 是 JavaScript 的注释符号,这样就可以避免 (在支持 JavaScript 的浏览器中)JavaScript 执行 –> 标签。

如果处于某种原因,你需要做兼容这类老旧浏览器,添加上面那种注释就十分必了。当然,现在的主流浏览器中我们都不必这么处理了。

IE 条件注释

IE 条件注释是一种特殊的 HTML 注释,这种注释只有 IE5.0 及以上版本才能理解。利用条件注释可以灵活的为不同版本 IE 浏览器导入不同 HTML 元素。例如:

<!--[if IE 8]> 
<link type="text/css" rel="stylesheet" href="ie8.css" />   
<![endif]-->

上面的注释就是给 IE8 浏览器添加特定的 ie8.css 样式。当然,我们还经常用条件注释给 HTML 标签添加不同的属性,来达到给不同版本的 IE 浏览器添加不同样式的目的。例如:

<!--[if IE 6 ]><html class="no-js ie ie6 lte6"><![endif]--> 
<!--[if IE 7 ]><html class="no-js ie ie7 lte7"><![endif]-->
<!--[if IE 8 ]><html class="no-js ie ie8 lte8"><![endif]-->
<!--[if IE 9 ]><html class="no-js ie ie9 lte9>"><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="no-js"><!--<![endif]-->

这种两种方式都可以达到给不同版本的 IE 浏览器添加不同样式的目的。只是前者需要单独创建一个不同的 .css 文件,而后面一种处理方式则是把所有的样式都写入一个文件,通过不同的 CSS 选择器来设置不同的样式。

当然,除了样式,我们也可以给不同版本 IE 浏览器添加特定的 .js 文件。例如:

<!--[if IE 8]> 
<script type="text/javascript" src="ie8.js"></script>   
<![endif]-->

现在你可能一下还看不不懂这些注释是什么意思,没关系,下面就来讲解这些符号都代表什么意思。

条件注释的语法

<!--[if 判断条件 IE 版本]>仅IE5.5可见<![endif]-->

判断条件

  • gt : greater than,选择条件版本以上版本,不包含条件版本;
  • lt : less than,选择条件版本以下版本,不包含条件版本;
  • gte : greater than or equal,选择条件版本以上版本,包含条件版本;
  • lte : less than or equal,选择条件版本以下版本,包含条件版本;
  • ! : 选择条件版本以外所有版本,无论高低;

条件注释判断条件具体的使用方法如下:

<!--[if IE 5]>仅IE5.5可见<![endif]-->

<!--[if gt IE 5.5]>仅IE 5.5以上可见<![endif]-->

<!--[if lt IE 5.5]>仅IE 5.5以下可见<![endif]-->

<!--[if gte IE 5.5]>IE 5.5及以上可见<![endif]-->

<!--[if lte IE 5.5]>IE 5.5及以下可见<![endif]-->

<!--[if !IE 5.5]>非IE 5.5的IE可见<![endif]-->

怎么样,现在清楚怎么使用 IE 的条件注释了吧?

在早些年,前端开发人员还必须兼容各个不同版本的 IE 浏览器,当时条件注释还是一个很不错的处理兼容性的方法。现在 IE 基本都是只需要支持 IE9 以上就可以了,而这些高版本的 IE 的渲染差别也没有那么大了,兼容性好处理多了,条件注释这个技术也慢慢使用少了。

IE6 注释(文字溢出)Bug

<div class="parent-element">
    <div class="float-element-one"></div>  
    <!-- 下面的文字将重复-->  
    <div class="float-element-two">这行文字在IE6中会被重复</div>  
</div>

像这一个布局结构,parent-element 元素内有 float-element-one 和 float-element-two 是两个浮动元素。在 IE6 中查看,float-element-two 最后的文字会重复出现,而且是注释的文字越长,重复的字数就越多。

引发 Bug 的条件

  • (parent-element)父容器包含两个具有“float”属性的子容器;
  • 第二个容器的宽度大于父容器的宽度,或者父容器宽度减去第二个容器宽度的值小于3px;
  • 在第二个容器前存在注释;

解决方案

  • 给所有浮动元素添加:display:inline;;(这个视乎似最有效的办法)
  • 给第二个浮动元素(最后一个)添加 margin-right:-3px;;(在满足页面布局的前提下可以使用。但是当情况比较复杂的时候,可能实施起来比较困难。)
  • 使用条件注释, i.e. <!--[if !IE]>注释的说明文本(下面的文字将重复)<![endif]-->(还不错的解决方案,但是并不是每个人都对这种注释写法很欣赏。);
  • 在父容器最后加上一个空的 <div> 标签;(多余的代码,感觉不怎么好)
  • 去掉所有注释(最直接的做法,但是“没有注释的代码”,的确不是一个好的代码写作习惯);

JavaScript 操作注释元素

关于注释标签最后一个要讨论的问题就是如何使用 JavaScript 获得注释元素?以下是我在 Stack Overflow找到的解决方案。

Using a NodeIterator (IE >= 9)

最好的方法是使用一个专用的 NodeIterator 实例迭代器获得给定根元素中包含的所有注释元素。

function filterNone() {
    return NodeFilter.FILTER_ACCEPT;
}

function getAllComments(rootElem) {
    var comments = [];
    // Fourth argument, which is actually obsolete according to the DOM4 standard, is required in IE 11
    var iterator = document.createNodeIterator(rootElem, NodeFilter.SHOW_COMMENT, filterNone, false);
    var curNode;
    while (curNode = iterator.nextNode()) {
        comments.push(curNode.nodeValue);
    }
    return comments;
}

window.addEventListener("load", function() {
    console.log(getAllComments(document.body));
});

Using a custom-made DOM traversal (to support IE < 9 as well)

如果您必须支持旧浏览器(例如IE <9),则需要自行遍历DOM,并提取节点类型为 Node.COMMENT_NODE 的元素。

// Thanks to Yoshi for the hint!
// Polyfill for IE < 9
if (!Node) {
    var Node = {};
}
if (!Node.COMMENT_NODE) {
    // numeric value according to the DOM spec
    Node.COMMENT_NODE = 8;
}

function getComments(elem) {
  var children = elem.childNodes;
  var comments = [];

  for (var i=0, len=children.length; i<len; i++) {
    if (children[i].nodeType == Node.COMMENT_NODE) {
      comments.push(children[i]);
    }
  }
  return comments;
}

提取注释节点的内容和删除节点

通过上面的方法获得注释节点(commentObject),获取注释内容很简单:

commentObject.nodeValue

移除的操作要稍微繁琐一点:

commentObject.parentNode.removeChild(commentObject)

SHARE THIS PAGE

免责声明:本站文章中的观点都是作者个人观点,并没有以任何方式反映他所属机构的意见。

发表评论