今天同事 明城 在项目中碰到一个 BUG,代码具体如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Firefox下innerHTML的一个BUG</title>
<style type="text/css">
a { display: block; border: 1px solid red;}
div { display: inline; border: 1px solid red;}
</style>
</head>
<body>
<a href="javascript:change();">change<div id="count">20</div>aaa</a>
<script type="text/javascript">
function change() {
var count = document.getElementById('count');
var c = count.innerHTML;
var page = parseInt(c)+1;
count.innerHTML = page;
alert(page);
}
</script>
</body>
</html>
当你在 Firefox2.0+ 或 Firefox3.0+ 中点击链接后,会发现 innerHTML 插入的内容为<a>21</a>,而其他浏览器测试(IE6、IE7、Safari3.0+、Opera9.0+)都正常,插入内容均为文字 21。
估计是 Firefox 的一个 BUG,查找了官方网站的 BUG库,果真找到别人提交的该类问题——《Setting innerHTML on a block element inside an inline element creates extra copies of the inline element》(Bug 381808)。
我们可以参阅下8楼的 Boris Zbarsky 给出的个人解释:
There are two separate concepts of block vs inline. One in CSS and one in
HTML. They don't match.In any case, the point is that in HTML <b> is not allowed to contain <div> (so
the <b> needs to get closed), but the text needs to be bold for compat so we do
residual style handling. HTML5 is going to define a different method of doing
this anyway, so at that point we'll need to revisit this bug.
虽然这是一个 BUG,但 BUG 的造成也却是人为的不良习惯造成的,在 WEB 标准中严格来说内联元素是不允许包含块级元素的(扩展阅读:《Allowed nesting of elements in HTML 4 Strict (and XHTML 1.0 Strict)》)。
witter:
共有18 条评论
可以忽略的bug,不可忽视的“人为的不良习惯”。
最后的扩展阅读也可以看 Junchen 写的《(X)HTML Strict 下的嵌套规则》
你好,博主!你那个源代码的地方是否用了什么插件?如果用了,可否告知是什么插件,或者发到我的邮箱,谢谢!
这结构。。。只能说FF太严格。。。
根据xhtml规范,行内元素可以继承块级元素,反过来就不行。《css权威指南》一书如是说的。
这是在帮同事 review 代码的时候发现的,当时改成 span 就解决了问题,不过我不能解释这个原因,感谢“怪飞”同学~
=.= a里面套个DIV是过不了W3C的 从不这样搞=。=
@青色 没有用插件,仅用的原生的标签:pre和code
其实这个问题是普遍遇到的,不仅仅是在利用JavaScript时会有这样的问题,某些情况下对CSS也会有较大的影响。所以使用语义的严格的HTML是非常有必要的。http://dancewithnet.com/2007/06/21/xhtml11_tags_list/这里有所有的HTML标签父子关系列表。
养成良好书写代码习惯,很多bug其实是可以避免的!
@秦歌 是的,理解语义,掌握嵌套规则,是作为前端最基本的要求,谢谢你提供的链接,很有价值^^
难道是我浏览器的毛病,我这ff3怎么出现了NaN值啊?
@lolocoo NaN值就对了parseInt处理的不是数字开头的,而是a元素开头的
恩w3c标准的问题
用span替换div解决吧.
我一帮都会用jquery,兼容性比较好,能够实现统一的效果
知其然知其所以然也是有好处的,呵呵
恩恩。把div换成span 就OK了
document.getElementById(‘count’).innerHTML是string型
document.getElementById(‘count’).innerHTML = page 右边是number型
最后得到结果document.getElementById(‘count’).innerHTML 是 string
但:
var m=”mm”
m=21
最后得到结果是m是number
奇怪