html5有两大特点:首先,强化了web网页的表现性能。其次,追加了本地数据库等web应用的功能。
广义论及html5时,实际指的是包括html、css和javascript在内的一套技术组合。它希望能够减少浏览器对于需要插件的丰富性网络应用服 务(plug-in-based rich internet application,ria),如adobe flash、microsoftsilverlight与oracle javafx的需求,并且提供更多能有效增强网络应用的标准集。
目前html5已向开发人员提供了很多新的标签,如section,nav,article,header和footer等。这些标签语义化程度高,会被经常使用,但在ie6,ie7,ie8和firefox2等老式浏览器中却不能识别和正常使用。
一、html5标签在浏览器展示存在的问题
对于现阶段来说,使用html5标签可能遇到的最大问题就是如何在不支持新标签的浏览器中做恰当的处理。当我们在页面中使用html5元素时,可能会得到三种不同的结果。
结果1:标签被当作错误处理并被忽略。那么dom构建的时候,就会当作这个标签不存在。
结果2:标签会被当作错误处理,并在dom构建的时候依然会按照预期的代码进行创建,并且html标签会被构造成行内元素(也就是说虽然不能识别,但是代码里section标签依然会在dom中创建一个对应section节点,但是属于行内元素)。
结果3:标签被识别为html5标签,然后用dom节点对其进行替换。dom在构建的时候和预想的一致,并且合适的样式会应用到标签上(大部分情况下是块级元素)。
有一个具体的例子,大家思考一下下面的代码:
titletext
很多浏览器(比如firefox 3.6和safari4)解析的时候都会将div作为最外层的元素,然后div里面是一个识别不了的元素(section),它会在dom中创建,并被作 为一个行内元素存在。h1和p元素都是作为section元素的子节点。因为section在dom中真实存在,所以也可以修改其样式。这种情况对应结果 2。
ie9之前的版本会认为section标签是一个错误,并直接将其忽略,那么h1和p标签会被解析,然后成为div标签的子节点。也会被认为是一个错误并直接跳过。在这些浏览器中实际有效的代码是这样的:
title
text
那么,旧版本的ie浏览器除了生成的dom结构和其他浏览器不一样,其对不可识别标签的容错能力还是很棒的。因为section节点没有在dom树中构建,所以也就不能给其增加样式。这种情况对应结果1。
当然,支持html5的浏览器比如ie9,firefox4+,safari5+会创建正确的dom结构,然后这些标签会默认附带html5规范中定义的默认样式。
那么,我们所面临的最大问题就是同样的代码在不同的浏览器中形成了不同的dom结构,并且含有不同的样式。
二、如何解决html5标签不兼容
或许会有很多人在质疑:为什么老式的浏览器不能识别这些标签?其实错不在浏览器,因为在那个时代根本不存在这种标签,所以不能正确识别出来,而这种不寻常 的标签识别令dom结构变得异常。对此,人们想出了很多在现阶段页面中使用html5元素的解决方案。每一个解决方案为了做到兼容都会遇到一些特定的问题。跟大家分享一下:
1、实现标签被识别
我曾做个一个测试(以ie8为例),是一个文章标题和蓝色字的文章内容,其中文章内容用了article标签。代码如下:
文章标题这是文章内容,应该是一段蓝色的文字。在老式浏览器中,如果不做hack将显示异常。
在ie8浏览器中,显示如下:ie8不能识别article标签, 定义在标签上的css样式没有起作用。 在ie8中,被解释成命名为和
两个空的标签元素,与文章内容并列为兄弟节点,如下图所示:既然因为不能识别标签而不能使用,那我的解决办法就是让标签被识别出来。所幸,简单地通过 document.createelement(tagname)即可以让浏览器识别标签和css引擎知道该标签的存在。假设我们上面的例子 的
区域加上如下代码:
ie8浏览器中的dom解释就会变成下图所示:自然,文字也显示成正常的蓝色。如下图所示:
2、javascript解决方案
javascript解决方案目的是解决在旧版本的ie中样式应用的问题。老版本的ie不会识别不明元素已经是一个耳熟能详的特性,而如果这些元素已经通 过document.createelement创建,那么浏览器就可以识别这些标签,并可以将其在dom树中构建,然后允许开发者对其应用样式。
这个方法可以确保html5标签能在旧版本ie中对应创建dom节点,然后可以对其应用样式。这个方法将html5块级元素设置成display:block,从而可以在各个浏览器中做到兼容。
今天测试把网页改成了html5的,调试了一下,在ff和opera中都显示正常了,到了ie6上却变得面目全非了。对此我还特意去找了一些使用js代码支持html5标签元素的方法,在此也跟大家分享一下:
(1)使用html5shiv
查看了一下,发现了html5shiv能解决这个问题,可以把html5的新元素转换成ie6认识的内容。只需要在你的head中调用这段代码就行:
当然你也可以直接把这个文件下载到自己的网站上。但这个文件必须在head标签中调用,因为ie必须在元素解析这前知道这些元素,才能启作用!
但还要提醒你一下:
还要在你的css文件中加上以下代码,不然有可能会出现些莫名其妙的问题。
header,nav,article,section,aside,footer{display:block;}
另外excanvas.js是google为ie6支持canvas元素写的脚本,以后我会跟大家再细说这样的例子,感兴趣的朋友可以去试试。
(2)使用kill ie6
除此之外你还可以使用kill ie6一族,前提是你的浏览器允许执行js文件。方法很简单,在你的网站的之前加上以下代码就可以了:
上面写的前缀html5是纯粹是用于这个例子而且也不是官方支持的,你甚至可以用"foo"作为前缀,结果还是一样。有了前缀之后,ie会识别新的元素,从而可以应用样式。在其他浏览器中一样有效,那么最后,你就成功地在各个浏览器中构建了一样的元素和一样的样式。
这个方法的缺陷很明显:你必须在html文档中使用xml格式的命名空间,同样,你也需要在css中这么做:
html5\:section {
display: block;
}
点评:这并不是我期望web开发者编写代码的方式。虽然这是一个非常杰出的解决方案,但是这让应用变得不自然。我不希望看到文件中充满了带命名空间的元素。
4、bulletproof技术(防弹衣技术)
说实话,我是第一次接触到这个技术,建议在所有新的html5块级元素中增加一个内部的div元素,然后包含一个css class,用这个元素来替代html元素(类似在里面穿了一件防弹衣),例如:
在应用样式的时候,tantek推荐直接给div增加样式,而不是给新元素增加样式
推荐使用:
.section {
color: blue;
}
而不是:
section {
color: blue;
}
这个方案的原理是用简单的方式将原来的样式应用方式转移到一个代表了html5标签的元素上。由于我一般情况下不会将样式通过标签名的方式应用到元素上,所以也并不完全支持这个建议。
这个方案的缺陷是不同的浏览器构建了不同的dom结构,那么你必须在编写javascript和css的时候格外小心。获取子节点或者父节点的时候,不同的浏览器返回的结果可能会不一样。特别是在下面的代码中:
5、反向的bulletproof技术
还有一些方法,比如尝试使用和tanteck方案相反的技术,也就是把html5元素放在div元素内部,例如:这个方案唯一的不同是html5元素的位置,其他都一样。喜欢这个技术的支持者认为他的一致性很好(适用于所有的元素,包括)。但是dom结构的不同让这个方案意义变得不大。他的主要优势是技术上的一致性。
6、关于x-ua-compatible的使用
目前绝大多数网站都用以下代码来作为ie8的兼容方法。
虽然微软将ie向标准迈进了一大步,而事实上ie8还存在一系列渲染的奇怪现象是不争的事实。
在x-ua-compatible中可用的方法有:
其中最后一行是永远以最新的ie版本模式来显示网页的。
另外加上
而使用,emulate模式后则更重视。所以目前来说还是以使用
为首选。
7、通过修改html部分来实现
我的主要目标是确保我只需要修改html部分。这就意味着不需要修改css和javascript。为什么会有这样的需求?需要修改的web应用视图越 多,你越有可能制造bug。将改变限制到一个视图也就限制了bug的出现,即使出现了bug,也可以减少你查找错误的范围。如果一个视图破相了,我可以知 道这是因为我增加了一个section元素,而不是考虑是不是css文件修改来带的影