由于html标签嵌套错误引发的一些问题

前一阵写代码的时候遇到了一些很莫名奇妙的现象,代码的运行结果与我的预期出入很大,但是程序本身并没有错误。当时我正在为自己写的一个小程序写文档,格式为html,因为有很多的JS代码,为了便于阅读自己添加了一些实现代码高亮显示的代码。代码并不是很复杂,当时我的页面中存在很多这种结构的HTML:
<h2>sub title</h2>
<p>
some text
<xmp id="code" style="display:none;">
some javascript codes;
</xmp>
</p>

因此我写了一个程序

var i, len, code, p, xmp, xmps = document.getElementsByTagName('xmp');
for(i=0, len=xmps.length; i<len; i++){
xmp = xmps[i];
code = xmp.innerHTML;
p = document.createElement('p');
p.innerHTML = gitHighLightCode(code);
xmp.parentNode.appendChild(p);
}

但运行之后却发现Firefox和Chrome下高亮显示的代码被紧挨着显示了通过在Google上搜索很快找到了答案:错误的标签嵌套。我原本希望我的代码运行后形成下面的HTML结构:
<h2>sub title</h2>
<p>
some text
<xmp id="code" style="display:none;">
some javascript codes;
</xmp>
<p>
high light codes....
</p>
</p>

但按照w3c的规范这p标签内部包含行inline标签,不能包含block标签,而xmp p恰好是block标签,所以属于非法嵌套。浏览器做了自动容错处理,在代码初始化的时候把XMP标签提到了p标签的外层变成了body的子节点,也就是如下的结构:

<h2>sub title</h2>
<p>
some text
</p>
<xmp id="code" style="display:none;">
some javascript codes;
</xmp>

因此运行后就变成了如下的结构

<h2>sub title</h2>
<p>
some text
</p>
<xmp id="code" style="display:none;">
some javascript codes;
</xmp>
<p>
high light codes....
</p>

知道原因之后做了写调整把xmp换成了textarea,这样应该就没问题了。运行之后FireFox确实如我预期生成了我要的代码结构,但IE下居然报错了:"未知的运行时错误",这个错误让人摸不着头脑。又Google了下发现还是嵌套错误引起的。原来我的代码高亮程序生成的html代码会在最外层生成一个div,因此用来显示代码的p标签内部嵌套了一个div, 而IE在对innerHTML赋值的时候对结构进行检查,如果发现标签嵌套错误就会报这个让人摸不到头脑的错误。如果你想引发这个错误可以尝试如下代码:

p = document.createElement('p');
p.innerHTML = '<p>code</p>';

其他浏览器虽然不会报错,但一旦遇到非法嵌套浏览器都会做自动容错处理,很多时候得到
的结果和我们原来的也不一样,比如下面的代码:
p = document.createElement('p');
p.innerHTML = '<p>code<p>code</p></p>';
document.body.appendChild(p);
alert(p.innerHTML); //输出结构为<p>code</p><p>code</p><p></p>


经过这一折腾我估计标签签嵌套会引发的错误让我差不多都尝了一遍。结论有几个:
1. 请严格按照w3c规范正确的嵌套标签否则浏览器会做自动容错处理,导致与我们预期不符的标签结构

2. p标签虽然为block标签但内部只允许出现inline标签,不允许出现其他block标签,因此不用在内部使用p、div、xmp等block标签

3. 如果使用innerHTML设置标签的内部HTML结构,IE会对标签结构做检查,如果出现非法嵌套会报错误:"未知的运行时错误"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值