IE、FF、Safari、OP不同浏览器兼容报告
1 浏览器内核简介
Trident |
IE浏览器(GreenBrowser绿色浏览器, 遨游浏览器....都是IE) |
Geckos |
FireFox |
Presto |
Opera |
Webkit |
Safari、Chrome |
浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“解释引擎”,不过我们一般习惯将之称为“浏览器内核”。负责对网页语法的解释(如HTML、JavaScript)并渲染(显示)网页。
所以,通常所谓的浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不同的浏览器内核对网页编写语 法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染(显示)效果也可能不同,这也是网页编写者需要在不同内核的浏览器中测试网页显示效果的原 因。
浏览器内核很多,如果加上所有的几乎没有什么人在用的非商业的免费内核,那么可能大约有10款以上甚至更多,不过通常我们比较常见的大约只有以下四种,下面先简单介绍一下。
1.1 Trident:
IE浏览器使用的内核,该内核程序在1997年的IE4中首次被采用,是微软在Mosaic代码的基础之上修改而来的,并沿用到目前的IE8。 Trident实际上是一款开放的内核,其接口内核设计的相当成熟,因此才有许多采用IE内核而非IE的浏览器涌现(如 Maxthon、The World 、TT、GreenBrowser、AvantBrowser等)。此外,为了方便也有很多人直接简称其为IE内核(当然也不排除有部分人是因为不知道内 核名称而只好如此说)。
由于IE本身的“垄断性”(虽然名义上IE并非垄断,但实际上,特别是从Windows 95年代一直到XP初期,就市场占有率来说IE的确借助Windows的东风处于“垄断”的地位)而使得Trident内核的长期一家独大,微软很长时间 都并没有更新Trident内核,这导致了两个后果——一是Trident内核曾经几乎与W3C标准脱节(2005年),二是Trident内核的大量 Bug等安全性问题没有得到及时解决,然后加上一些致力于开源的开发者和一些学者们公开自己认为IE浏览器不安全的观点,也有很多用户转向了其他浏览 器,Firefox和Opera就是这个时候兴起的。非Trident内核浏览器的市场占有率大幅提高也致使许多网页开发人员开始注意网页标准和非IE浏 览器的浏览效果问题。
1.2 Gecko:
Netscape6开始采用的内核,后来的Mozilla FireFox也采用了该内核,Gecko的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。因为这是个开源 内核,因此受到许多人的青睐,Gecko内核的浏览器也很多,这也是Geckos内核虽然年轻但市场占有率能够迅速提高的重要原因。
事 实上,Gecko引擎的由来跟IE不无关系,前面说过IE没有使用W3C的标准,这导致了微软内部一些开发人员的不满;他们与当时已经停止更新了的 Netscape的一些员工一起创办了Mozilla,以当时的Mosaic内核为基础重新编写内核,于是开发出了Geckos。不过事实上,Gecko 内核的浏览器仍然还是Firefox用户最多,所以有时也会被称为Firefox内核。此外Gecko也是一个跨平台内核,可以在Windows、 BSD、Linux和Mac OS X中使用。
1.3 Presto:
目前Opera采用的内核,该内核在2003年的Opera7中首次被使用,该款引擎的特点就是渲染速度的优化达到了极致,也是目前公认网页浏览速度最快的浏览器内核,然而代价是牺牲了网页的兼容性。
实际上这是一个动态内核,与前面几个内核的最大的区别就在脚本处理上,Presto有着天生的优势,页面的全部或者部分都能够在回应脚本事件时等情况下 被重新解析。此外该内核在执行Javascrīpt的时候有着最快的速度,根据在同等条件下的测试,Presto内核执行同等Javascrīpt所需的 时间仅有Trident和Gecko内核的约1/3(Trident内核最慢,不过两者相差没有多大)。那次测试的时候因为Apple机的硬件条件和普通 PC机不同所以没有测试WebCore内核。只可惜Presto是商业引擎,使用Presto的除开Opera以外,只剩下NDSBrowser、Wii Internet Channle、Nokia 770网络浏览器等,这很大程度上限制了Presto的发展。
1.4 Webkit:
苹果公司自己的内核,也是苹果的Safari浏览器使用的内核。 Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍生而来,它们都是自由软 件,在GPL条约下授权,同时支持BSD系统的开发。所以Webkit也是自由软件,同时开放源代码。在安全方面不受IE、Firefox的制约,所以 Safari浏览器在国内还是很安全的。
限于Mac OS X的使用不广泛和Safari浏览器曾经只是Mac OS X的专属浏览器,这个内核本身应该说市场范围并不大;但似乎根据最新的浏览器调查表明,该浏览器的市场甚至已经超过了Opera的Presto了——当然 这一方面得益于苹果转到x86架构之后的人气暴涨,另外也是因为Safari 3终于推出了Windows版的缘故吧。Mac下还有OmniWeb、Shiira等人气很高的浏览器。
google的chrome也使用webkit作为内核。
WebKit 内核在手机上的应用也十分广泛,例如 Google 的手机 Gphone、 Apple 的 iPhone, Nokia’s Series 60 browser 等所使用的 Browser 内核引擎,都是基于 WebKit。
2 Safari特点:
Safari被称作世界上最快的浏览器。但是,新发布的Safari 5从性能上来说已经远远超越了其上一个版本。苹果公司称,Safari 5的运行速度要比Safari 4快30%,比Chrome 5.0快3%。Safari 5的运行速度甚至是Firefox 3.6的2倍多。
增加了一个Reader(阅读器),取代了以往的RSS Reader。
与其他主流浏览器一样,也增加了一个默认搜索引擎的选项;
包含了Safari 5开发工具。其中有一个“web检查器”可以显示Safari与网站的整个交互过程;
增强了对HTML5的支持:包括Geolocation、全屏幕HTML5视频、HTML5视频隐藏式字幕、新的分节元素(article、 aside、footer、header、hgroup、nav和section)、HTML5 AJAX 历史记录、EventSource、WebSocket、HTML5可拖移属性、HTML5表格验证以及HTML5 Ruby。
Windows版本的Safari 5将支持GPU浏览加速。这也是很多浏览器的新特征,可以达到更快的浏览速度;
历史记录可以按照日期搜索了。
Safari 5采用Nitro JavaScript引擎。Mac版Safari 5运行JavaScript脚本的速度比Safari 4快30%,比Chrome 5.0快3%,几乎达到火狐3.6的两倍。
2.1 速度对比
通过使用DNS预读取,以及改进的网页缓存技术,Safari 5可以更快地打开网页。
Safari 5的扩展应用得到沙箱技术的保护,从而提高了安全性和稳定性。
2.2 CSS兼容能力对比
2.3 JavaScript兼容对比
数值越小越好
以上数据来源: http://pcedu.pconline.com.cn/pingce/pingcenormal/0906/1678394.html
3 CSS区别及兼容
3.1 什么是CSS hack?
由于不同的浏览器,比如IE6、IE7、IE8、Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果。
这个时候我们就需要针对不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果。
这个针对不同的浏览器写不同的CSS code的过程,就叫CSS hack,也叫写CSS hack。
不同的浏览器对CSS的解释都有一点出入,特别是padding, line-height这些要细微控制的地方,下面的hack基本可以解决这个问题:
在属性前加下划线(_),那么此属性只会被IE6解释
在属性前加星号(*),此属性只会被IE7解释
在属性值后面加"\9",表示此属性只会被IE8解释
3.2 各浏览器CSS hack兼容表:
|
IE6 |
IE7 |
IE8 |
Firefox |
Chrome |
Safari |
|
IE6 |
IE7 |
IE8 |
FF |
CH |
Safari |
!important |
|
Y |
|
Y |
|
|
Y |
Y |
Y |
Y |
Y |
Y |
|
_ |
Y |
|
|
|
|
|
Y |
|
|
|
|
|
|
* |
Y |
Y |
|
|
|
|
Y |
Y |
|
|
|
|
|
*+ |
|
Y |
|
|
|
|
Y |
Y |
|
|
|
|
|
\9 |
Y |
Y |
Y |
|
|
|
Y |
Y |
Y |
|
|
|
|
\0 |
|
|
Y |
|
|
|
|
|
Y |
|
|
|
|
nth-of-type(1) |
|
|
|
|
Y |
Y |
|
|
|
|
|
|
整理二:IE6,IE7,FireFox,Opera,Safari兼容CSS的解决方法及CSS差别
IE6,IE7,FireFox,Opera,Safari兼容CSS的解决方法及CSS差别
有意思的测试地址: http://knb.im/css3/
3.3 CSS HACK
以下两种方法几乎能解决现今所有HACK.
1, !important
随着IE7对!important的支持, !important 方法现在只针对IE6的HACK.(注意写法.记得该声明位置需要提前.)
2, IE6/IE7对FireFox
*+html 与 *html 是IE特有的标签, firefox 暂不支持.而*+html 又为 IE7特有标签.
注意:*+html 对IE7的HACK 必须保证HTML顶部有如下声明:
”http://www.w3.org/TR/html4/loose.dtd”>
3.4 常见CSS兼容性问题
div类
1. 居中问题
div里的内容,IE默认为居中,而FF默认为左对齐
可以尝试增加代码margin:auto
2. 高度问题
两上下排列或嵌套的div,上面的div设置高度(height),如果div里的实际内容大于所设高度,在FF中会出现两个div重叠的现象;但在IE中,下面的div会自动给上面的div让出空间
所以为避免出现层的重叠,高度一定要控制恰当,或者干脆不写高度,让他自动调节,比较好的方法是 height:100%;
但当这个div里面一级的元素都float了的时候,则需要在div块的最后,闭和前加一个沉底的空div,对应CSS是:
.float_bottom {clear:both;height:0px;font-size:0px;padding:0;margin:0;border:0;line-height:0px;overflow:hidden;}
3. clear:both;
不想受到float浮动的,就在div中写入clear:both;
4. IE浮动 margin 产生的双倍距离
#box {
float:left;
width:100px;
margin:0 0 0 100px; //这种情况之下IE会产生200px的距离
display:inline; //使浮动忽略
}
5. padding 问题
FF设置 padding 后,div会增加 height 和 width,但IE不会 (* 标准的 XHTML1.0 定义 dtd 好像一致了)
高度控制恰当,或尝试使用 height:100%;
宽度减少使用 padding
但根据实际经验,一般FF和IE的 padding 不会有太大区别,div 的实际宽 = width + padding ,所以div写全 width 和 padding,width 用实际想要的宽减去 padding 定义
6. div嵌套时 y 轴上 padding 和 marign 的问题
FF里 y 轴上 子div 到 父div 的距离为 父padding + 子marign
IE里 y 轴上 子div 到 父div 的距离为 父padding 和 子marign 里大的一个
FF里 y 轴上 父padding=0 且 border=0 时,子div 到 父div 的距离为0,子marign 作用到 父div 外面
7. padding,marign,height,width 的傻瓜式解决技巧
注意是技巧,不是方法:
写好标准头
高尽量用padding,慎用margin,height尽量补上100%,父级height有定值子级height不用100%,子级全为浮动时底部补个空clear:both的div
宽尽量用margin,慎用padding,width算准实际要的减去padding
列表类
1. ul 标签在FF中默认是有 padding 值的,而在IE中只有margin有值
先定义 ul {margin:0;padding:0;}
2. ul和ol列表缩进问题
消除ul、ol等列表的缩进时,样式应写成: {list-style:none;margin:0px;padding:0px;}
显示类
1. display:block,inline 两个元素
display:block; //可以为内嵌元素模拟为块元素
display:inline; //实现同一行排列的的效果
display:table; //for FF,模拟table的效果
display:block 块元素,元素的特点是:
总是在新行上开始;
高度,行高以及顶和底边距都可控制;
宽度缺省是它的容器的100%,除非设定一个宽度
,
,
15、在tr里,FF不支持“display:block”
Not compatible:
document.getElementById("hrmtr").style.display = "block";
Compatible:
document.getElementById("hrmtr").style.display = "";
16、FF使用滤镜功能时,要设置透明度
Not compatible:
filter:alpha(opacity=50);
Compatible:
filter:alpha(opacity=50);
-moz-opacity:0.5; /*css*/
/*The way in js*/
if (!window.isIE)
obj.style.MozOpacity = 0.5;
17、全选
在IE里我们可以用 “objInput.select()” 选中textbox里的值. 但在FF只能用focus().
Compatible:
if ( window.isIE )
{
document.mainform.elements[checkCategory].select();
}
else
{
document.getElementById(“checkCategory”).focus();
}
18、用js插入行或列时应注意:
Not compatible:
tr = tab.insertRow();
td = tr.insertCell();
Compatible:
tr = tab.insertRow(-1);
td = tr.insertCell(-1);
19、我们常常设置表格宽度和高度少于20px时,往往在FF里没有效果:
Not Compatible:
Compatible:
style="display: block;" src="/ clear.gif"/>
20、在IE里插入空白行时不会显示,但在FF里会显示出来
Not Compatible:
sbdTempHtml.Append("
sbdTempHtml.Append("
Compatible:
sbdTempHtml.Append("");
21、在IE里document.mainform.elements[“…”]可以取到对象,但FF不行:
Not Compatible:
document.mainform.elements[“imgID”]
Compatible
document.getElementById(“imgID”)
22、FF里有textContent属性,但IE只有innerText
Not Compatible:
div.innerText
Compatible
if(window.isIE)
{div.innerText}
else
{div.textContent}
23、在IE,attachEvent可以正常使用,但FF里有时不行,比如在iframe里:
Not Compatible:
obj.contentWindow.document.attachEvent("onkeyup", function(){updateCharCount(obj.id);});
Compatible
if(window.isIE)
{
obj.contentWindow.document.attachEvent("onkeyup", function(){updateCharCount(obj.id);});
}
else
{
obj.contentWindow.document.addEventListener("keyup", function(){updateCharCount(obj.id);},false);
}
24、runtimeStyle不支持,应改为style
25、window.execScript 不支持
var jsCode = "var a = 1;";
if (window.execScript) {
window.execScript(jsCode, "JavaScript");
} else {
window.eval(jsCode);
}
26、obj.style.display=”block”不支持,应为obj.style.display=””
27、document.createElement在FF和Safari里不支持直接传入HTML,如:
Not Compatible:
document.createElement("");
Compatible
var iframeObj = (document.all)?document.createElement(""):document.createElement('iframe');
iframeObj.name="iframe1";
iframeObj.id="iframe1";
iframeObj.width=0;
iframeObj.height=0;
document.body.appendChild(iframeObj);
28、在Ipad Safari里,不支持滚动条overflow.
29、在Ipad Safari里,不支持下载
if (!navigator.userAgent.match(/iPad/i)) {
Not Compatible:
f.src=url;
}
else
{
Compatible
window.open(url);
}
更多详细请google文章: Jscript Deviations from ES3
IE8里的64个BUG:
http://www.gtalbot.org/BrowserBugsSection/MSIE8Bugs/
7 常见JavaScript兼容性问题
集合类对象问题
现有代码中存在许多 document.form.item("itemName") 这样的语句,不能在 FF 下运行
解决方法:
改用 document.form.elements["elementName"]
说明:IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象.
解决方法:统一使用[]获取集合类对象.
window.event
现有问题:
使用 window.event 无法在 FF 上运行
解决方法:
FF 的 event 只能在事件发生的现场使用,此问题暂无法解决。可以这样变通:
原代码(可在IE中运行):
提交" οnclick="javascript:gotoSubmit()"/>
function gotoSubmit() {
alert(window.event); // use window.event
}
新代码(可在IE和FF中运行):
提交" οnclick="javascript:gotoSubmit(event)"/>
function gotoSubmit(e) {
e = e? e : (window.event ? window.event : null);
alert(e);
}
此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。所以,这种方案 tpl 部分仍与老代码兼容。
HTML 对象的 id 作为对象名的问题
现有问题:
在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 FF 中不能。
解决方法:
用 getElementById("idName") 代替 idName 作为对象变量使用。
用idName字符串取得对象的问题
现有问题:
在IE中,利用 eval(idName) 可以取得 id 为 idName 的 HTML 对象,在FF 中不能。
解决方法:
用 getElementById(idName) 代替 eval(idName)。
变量名与某 HTML 对象 id 相同的问题
现有问题:
在 FF 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。
解决方法:
在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。
event.x 与 event.y 问题
现有问题:
在IE 中,event 对象有 x, y 属性,FF中没有。
解决方法:
在FF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
如果要完全一样,可以稍麻烦些:
mX = event.x ? event.x : event.pageX;
然后用 mX 代替 event.x
其它:
event.layerX 在 IE 与 FF 中都有,具体意义有无差别尚未试验。
关于frame
现有问题:
在 IE中 可以用window.testFrame取得该frame,FF中不行
解决方法:
在frame的使用方面FF和ie的最主要的区别是:
如果在frame标签中书写了以下属性:
那么ie可以通过id或者name访问这个frame对应的window对象
而FF只可以通过name来访问这个frame对应的window对象
例如如果上述frame标签写在最上层的window里面的htm里面,那么可以这样访问
IE: window.top.frameId或者window.top.frameName来访问这个window对象
FF: 只能这样window.top.frameName来访问这个window对象
另外,在FF和ie中都可以使用window.top.document.getElementById("frameId")来访问frame标签
并且可以通过window.top.document.getElementById("testFrame").src = 'xx.htm'来切换frame的内容
也都可以通过window.top.frameName.location = 'xx.htm'来切换frame的内容
父结点的问题
在FF中没有 parentElement parentElement.children 而用 parentNode parentNode.childNodes
childNodes的下标的含义在IE和FF中不同,FF使用DOM规范,childNodes中会插入空白文本节点。
一般可以通过node.getElementsByTagName()来回避这个问题。当html中节点缺失时,IE和FF对parentNode的解释不同,例如
FF中input.parentNode的值为form, 而IE中input.parentNode的值为空节点
FF中节点没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)
const 问题
现有问题:
在 IE 中不能使用 const 关键字。如 const constVar = 32; 在IE中这是语法错误。
解决方法:
不使用 const ,以 var 代替。
body 对象
FF的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在
URLencoding
在js中如果书写url就直接写&不要写&例如var url = 'xx.jsp?objectName=xx&objectEvent=xxx';
frm.action = url那么很有可能url不会被正常显示以至于参数没有正确的传到服务器
一般会服务器报错参数没有找到
当然如果是在tpl中例外,因为tpl中符合xml规范,要求&书写为&
一般FF无法识别js中的&
nodeName 和 tagName 问题
现有问题:
在FF中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象有问题
解决方法:
使用 tagName,但应检测其是否为空。
元素属性
IE下 input.type属性为只读,但是FF下可以修改
document.getElementsByName() 和 document.all[name] 的问题
在 IE 中,getElementsByName()、document.all[name] 均不能用来取得多个具有相同name的div 元素集合。
兼容firefox的 outerHTML,FF中没有outerHtml的方法
if (window.HTMLElement) {
HTMLElement.prototype.__defineSetter__("outerHTML",function(sHTML) {
var r=this.ownerDocument.createRange();
r.setStartBefore(this);
var df=r.createContextualFragment(sHTML);
this.parentNode.replaceChild(df,this);
return sHTML;
});
HTMLElement.prototype.__defineGetter__("outerHTML",function() {
var attr;
var attrs=this.attributes;
var str="<"+this.tagName.toLowerCase();
for (var i=0;i
attr=attrs[i];
if(attr.specified)
str+=" "+attr.name+'="'+attr.value+'"';
}
if(!this.canHaveChildren)
return str+">";
return str+">"+this.innerHTML+""+this.tagName.toLowerCase()+">";
});
HTMLElement.prototype.__defineGetter__("canHaveChildren",function() {
switch(this.tagName.toLowerCase()) {
case "area":
case "base":
case "basefont":
case "col":
case "frame":
case "hr":
case "img":
case "br":
case "input":
case "isindex":
case "link":
case "meta":
case "param":
return false;
}
return true;
});
}
自定义属性问题
说明:IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性;FF下,只能使用getAttribute()获取自定义属性.
解决方法:统一通过getAttribute()获取自定义属性.
event.srcElement问题
说明:IE下,even对象有srcElement属性,但是没有target属性;Firefox下,even对象有target属性,但是没有srcElement属性.
解决方法:使用obj(obj = event.srcElement ? event.srcElement : event.target;)来代替IE下的event.srcElement或者Firefox下的event.target.
window.location.href问题
说明:IE或者Firefox2.0.x下,可以使用window.location或window.location.href;Firefox1.5.x下,只能使用window.location.
解决方法:使用window.location来代替window.location.href.
模态和非模态窗口问题
说明:IE下,可以通过showModalDialog和showModelessDialog打开模态和非模态窗口;Firefox下则不能.
解决方法:直接使用window.open(pageURL,name,parameters)方式打开新窗口
如 果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用window.opener来访问父窗口. 例如:var parWin = window.opener; parWin.document.getElementById("Aqing").value = "Aqing";
事件委托方法
IE:document.body.onload = inject; //Function inject()在这之前已被实现
FF:document.body.onload = inject();
如果要加传递参数,可以做个闭包
(function(arg){
document.body.οnlοad=function(){inject(arg);};
})(arg)
innerText在IE中能正常工作,但是innerText在FireFox中却不行.
解决方法:
if(navigator.appName.indexOf("Explorer") > -1){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = "my text";
}
FF中类似 obj.style.height = imgObj.height 的语句无效
解决方法:
obj.style.height = imgObj.height + 'px';
IE,FF以及其它浏览器对于 table 标签的操作都各不相同,在ie中不允许对table和tr的innerHTML赋值,使用js增加一个tr时,使用appendChile方法也不管用
解决方法:
//向table追加一个空行:
var row = otable.insertRow(-1);
var cell = document.createElement("td");
cell.innerHTML = " ";
cell.className = "XXXX";
row.appendChild(cell);
8 手机及平板浏览器兼容测试结果
注意: 以下所说的“大多数”是指在我们测试过的机型中,发生此类状况的手机占比达50%及以上,“部分”为 20%到50%;“少数”为20%及以下。而这个概率也仅仅只限于我们所测试过的机型,虽然我们采集的样本尽量覆盖各种特征的手机,但并不代表所有手机的 情况。
8.1.1.1 XHTML部分
大多数手机不支持的:
- 表单元素的“disable”属性
部分手机不支持的:
- “button”标签
- “input[type=file]“标签
- “iframe”标签。
虽然只有部分 手机不支持这几个标签,但因为这些标签在页面中往往具有非常重要的功能,所以属于高危标签,要谨慎使用。
少数手机不支持的:
- “select”标签:该标签如果被赋予比较复杂的CSS属性,可能会导致显示不正常,比如”vertical-align:middle”。
8.1.1.2 CSS部分
大部分手机不支持的:
- “font-family”属性:因为手机基本上只安装了宋体这一种中文字体;
- “font-family:bold;”:对中文字符无效,但一般对英文字符是有效的;
- “font-style: italic;”:同上;
- “font-size”属性:比如12px的中文和14px的中文看起来一样大,当字符大小为18px的时候你也许能看出来一些区别;
- “white-space/word-wrap”属性:无法设置强制换行,所以当你网页有很多中文的时候,需要特别关注不要让过多连写的英文字符 撑开页面;
- “background-position”属性:但背景图片的其他属性设定是支持的;
- “position”属性;
- “overflow”属性;
- “display”属性;
- “min-height”和”min-weidth”属性;
部分手机不支持的:
- “height”属性:对”height”的支持不太好,奇怪的是在我们的测试当中,仅仅只有很少部分手机不支持”width”属性;
- “pading”属性
- “margin”属性:更高比例的手机不支持”margin”的负值。
少数手机不支持的:
- 少数手机对CSS完全不支持;
8.1.1.3 JavaScript部分
这部分测试相对不那么让人抓狂,要么干脆不支持,如果支持的话,对基本的dom操作、事 件等支持度都还不错。但我们没有测试过很复杂的脚本。
在我们测试过的手机当中,支持(包括不完全支持)JavaScript的手机比例大约在一半左右,当然,对于我们来说,最重要的不是这个比例,而是要如何做好JavaScript的优雅降级。
8.1.1.4 其他
· 部分手机不支持png8和png24,所以尽量使用jpg和gif的图片
· 另外对于平滑的渐变等精细的图片细节,部分手机的色彩支持度并不能达到要求,所以慎用有平滑渐变的bar设计
· 部分手机对于超大图片,既不进行缩放,也不显示横下滚动条
· 少数手机在打开超过20k的测试页面时,会显示内存不足
8.1.2 开发中你需要注意的问题
1. 手机网页编码需要遵循什么规范?
遵循XHTML Mobile Profile规范(WAP-277-XHTMLMP-20011029-a.pdf ), 简称为XHTML MP,也就是通常说的WAP2.0规范。 XHTML MP是为不支持XHTML的全部特性且资源有限的客户端所设计的。它以XHTML Basic为基础,加入了一些来自XHTML 1.0的元素和属性。这些内容包括一些其他元素和对内部样式表的支持。和XHTML Basic相同,XHTML MP是严格的XHTML 1.0子集。
2. 网页文档推荐使用扩展名?
推荐命名为xhtml,按WAP2.0的规范标准写成html/htm等也是可以的。但少数手机对html支持的不好。
3. 为什么现今大多数的网站一行字数上限为14个中文字符?
由于手持设备的特殊性,其页面中实际文字大小未必是我们在CSS中设定的文字大小,尤其是在第三方浏览器中。例如Nokia5310,其内置浏览器 页面内文字大小与CSS设定相符,但是第三方浏览器OperaMini与UCWEB页面内文字大小却大于CSS设定。经测试,其文本大概在16px左右。 假如屏幕分辨率宽度为240px,去除外边距,那么其一行显示14个字以内,是比较保险(避免文本换行)的做法。
4. 使用WCSS还是CSS?
WCSS (WAP Cascading Style Sheet 或称 WAP CSS)是移动版本的CSS样式表。它是CSS2的一个子集,去掉了一些不适于移动互联网特性的属性,并加入一些具有WAP特性的扩展(如-wap- input-format/-wap-input-required/display:-wap-marquee等)。 需要留意的是,这些特殊的属性扩展并不是很实用,所以在实际的项目开发当中,不推荐使用WCSS特有的属性。
5. 避免空值属性
如果属性值为空,在web页面中是完全没有问题的,但是在大部分手机网页上会报错。
6. 网页大小限制
建议低版本页面不超过15k,高版本页面不超过60k。
7. 用手机模拟器和第三方手机浏览器的在线模拟器来测试页面是不是靠谱?
有条件的话,我们当然建议在手机实体上进行测试,因为目标客户群的手机设备总是在不断变化的,这些手机模拟器通常不能完全正确的模拟页面在手机上的显示情 况,比如图片色彩,页面大小限制等就很难再模拟器上测试出来。当然,一些第三方手机浏览器的在线模拟器还是可以进行测试的,第三方浏览器相对来说受手机设 备的影响较小。
9 Javascript+HTML+CSS编码规范
9.1 目标
为提升公司在WEB开发中的前端脚本和样式表编码的规范性,提出了一些前端开发的基本准则。
9.2 准则
l WEB应用应尽量减少使用服务器端控件,多采用JavaScript和客户端控件或是AJAX方式实现功能。
l 公司产品中新开发的WEB项目全部使用公司JS框架-Jcore组件,公司承接的基于WEB的客户项目也采用Jcore组件。对于客户内部项目可以在客户本地服务器上部署一份Jcore服务
l 所有采用Jcore框架的项目,JS编码和使用到的UI组件库,如果Jcore核心库或UI库已经提供的,一律采用Jcore框架内提供的相关库;如果Jcore框架还未提供的UI库或是公共函数,可以向Jcore开发组提出需求。
l 不允许在JS脚本中定义配置,应统一将配置定义在Web.Config中,以<%= %>形式引用。
l JavaScript对象命名使用Pascal命名约定,名称中每个单词的首字母用大写
变量和函数命名使用Camel命名约定,名称中的第一个单词小写,从第二个单词开始的首字母用大写。
函数内部变量/不应由外部调用的函数使用Camel命名约定,名称中的第一个单词小写,从第二个单词开始的首字母用大写,并以“_”作为前缀。
l 每项目建立一个全局样式表,名称为:main.css,其中存放所有通用样式。
每项目按照业务功能的不同,可单独定义其特定样式文件存放。
一个项目中的样式表文件不应过多,每个页面引用的样式表文件一般应少于2个(包括2个)。
l 对于公司产品中的WEB项目样式表,公司将提供几种风格的皮肤库,作为公共样式表,公共样式表包含常见的页面元素样式,命名上全部以w_开头,项目样式表编写规范参照CSS编码规范。
l 对于终端调用的WEB应用,编写的JavaScript和CSS需要满足IE6、IE7、IE8三个常见IE浏览器版本的兼容性。对于非终端调用的WEB应用,编写的JavaScript和CSS需要满足IE6、IE7、IE8、FireFox2.0及以上版本浏览器的兼容性。
l 关于多语言支持的具体要求后续补充。
l 对于JavaScript和CSS在项目正式部署的时候,需要利用公司指定的JavaScript发布工具对JavaScript和CSS文件进行代码压缩和自动去除注释,以减少JavaScript和CSS文件大小,减轻网络压力和加快页面加载速度。
9.3 JavaScript编码规范
9.3.1 变量命名
1) 一般变量
l 所有的变量名使用英文名称。
l 常量在对象(类)或者枚举变量的前部声明。
l 通用的变量必须使用与其名字一致的类型名称:
setTopic(topic) // 变量 topic 为 Topic 类型的变量
l 如果变量有其隐含的返回值,则避免使用其相似的方法:
getHandler(); // 避免使用 getEventHandler()
l 公有变量必须清楚的表达其自身的属性,避免字义含糊不清,例如:
MouseEventHandler // 而非 MseEvtHdlr。
dojo.events.mouse.Handler // 而非 dojo.events.mouse.MouseEventHandler
2) 类变量
l 类的命名使用骆驼命名规则,例如: Account, EventHandler
l 类/构造函数,可以使用扩展其基类的名称命名,这样可以正确、迅速的找到其基类的名称:
EventHandler UIEventHandler MouseEventHandler
l 私有变量,则前面添加下划线。 this._somePrivateVariable = statement;
l 私有类的变量属性成员使用混合名称(mixedCase)命名,并前面下下划线(_)。例如:
var MyClass = function()
{
var _buffer;
this.doSomething = function(){ };
}
l 方法的命令必须为动词或者是动词短语: obj.getSomeValue()
3) 枚举
l 枚举变量的命名必须要有实际的意义,并且其成员 必须 使用骆驼命名规则或使用大写:
var NodeTypes =
{
Element : 1,
DOCUMENT: 2
}
9.3.2 特殊命名规范
l 术语 "get/set" 不要和一个字段相连,除非它被定义为私有变量。
l 前面加 "is" 的变量名 应该 为布尔值,同理可以为 "has", "can" 或者 "should"。
l 术语 "compute" 作为变量名应为已经计算完成的变量。
l 术语 "find" 作为变量名应为已经查找完成的变量。
l 术语 "initialize" 或者 "init" 作为变量名应为已经实例化(初始化)完成的类或者其他类型的变量。
l UI (用户界面)控制变量应在名称后加控制类型,例如: leftComboBox, topScrollPane。
l 带有 "num" 或者 "count" 开头的变量名约定为数字(对象)。
l 重复变量建议使用 "i", "j", "k" (依次类推)等名称的变量。
l 补充用语必须使用补充词,例如: get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.
l 能缩写的名称尽量使用缩写。
l 避免产生歧义的布尔变量名称,例如:
isNotError, isNotFound 为非法错误类,建议在变量名称后加上 "Exception" 或者 "Error"。
9.3.3 逻辑语句
1) IF 语句:
l 多行
if (someCondition){
statements;
}else if (someOtherCondition){
statements;
}else {
statements;
}
l 单行,也可以这样写:
if (condition){ statement; }
2) FOR 语句 应该 看起来像这样:
l 多行
for (initialization; condition; update){
statements;
}
l 单行,也可以这样写:
for (intialization; condition; update){ statement; }
3) WHILE 语句 应该 看起来像这样:
l 多行
while (!isDone) {
doSomething();
isDone = moreToDo();
}
l 单行,也可以这样写:
while (condition){ statement; }
4) DO ... WHILE 语句 应该 看起来像这样:
Do{
statements;
}
while (condition);
5) SWITCH 语句 应该 看起来像这样:
switch (condition){
case ABC:
statements; // fallthrough
case DEF: statements;
break;
default:
statements;
break;
}
6) TRY ... CATCH 语句 应该 看起来像这样:
try {
statements;
} catch(ex) {
statements;
} finally {
statements;
}
9.3.4 注释
总结(summary): 简短的表述此函数或者对象实现的目的
描述(description): 对于此函数或者类的简短的描述
返回(return): 描述此函数返回什么(并不包括返回类型)
1) 基本函数信息
function(){
// summary: Soon we will have enough treasure to rule all of New Jersey.
// description: Or we could just get a new roomate.
// Look, you go find him. He don't yell at you.
// All I ever try to do is make him smile and sing around
// him and dance around him and he just lays into me.
// He told me to get in the freezer 'cause there was a carnival in there.
// returns: Look, a Bananarama tape!
}
2) 对象函数信息
{
// summary: Dingle, engage the rainbow machine!
// description:
// Tell you what, I wish I was--oh my g--that beam,
// coming up like that, the speed, you might wanna adjust that.
// It really did a number on my back, there. I mean, and I don't
// wanna say whiplash, just yet, cause that's a little too far,
// but, you're insured, right?
}
3) 参数
简单类型 :可以直接在函数参数定义中注释说明。
function(/*String*/ foo, /*int*/ bar)
可变类型参数
? :可选参数 说面参数范围不确定
[] :数组
function(/*String?*/ foo, /*int*/ bar, /*String[]*/ baz)
4) 变量
由于实例变量、原型变量和外部变量的声明是一致的,所以有很多的方法声明、修改变量。具体的如何定义和定位应在变量最先出现的位置指明变量的名称、类型、作用域等信息。
举例:
function foo() {
// myString: String
// times: int
// How many times to print myString
// separator: String
// What to print out in between myString*
this.myString = "placeholder text";
this.times = 5;
}
foo.prototype.setString = function (myString){
this.myString = myString;
}
foo.prototype.toString = function() {
for(int i = 0; i < this.times; i++) {
dojo.debug(this.myString);
dojo.debug(foo.separator);
}
}
foo.separator = "=====";
5) 返回值
因为函数可以同时返回多个不同(类型)的值,所以应每个返回值之后加入返回类型的注释。注释在行内注释即可,如果所有的返回值为同一类型,则指明返回的类型;如为多个不同的返回值,则标注返回类型为"mixed"。
举例:
function(){
if (arguments.length) {
return "You passed argument(s)"; // String
} else {
return false; // Boolean
}
}
6) 伪代码
有时候您需要在函数或者类中添加对于此函数和类的功能性流程描述。如果您打算这样做,您可以使用 /*======== (= 字符最好出现 5 次或者更多),这样做的好处就是可以不用将这些东西加入代码(译注:原作者的意思可能为代码管理系统)。这样看起来在 /*===== 和 =====*/ 会有非常长的一段注释,等待功能调整完毕以后就可以考虑是否删除。
举例:
/*=====
module.pseudo.kwArgs = {
// url: String
// The location of the file
url: "",
// mimeType: String
// text/html, text/xml, etc
mimeType: ""
}
=====*/
function(/*module.pseudo.kwArgs*/ kwArgs){
dojo.debug(kwArgs.url);
dojo.debug(kwArgs.mimeType);
}
9.4 HTML编码规范
l 所有的xhtml代码小写
l 属性的值一定要用双引号("")括起来,且一定要有值
l 每个标签都要有开始和结束,且要有正确的层次
l 空元素要有结束的tag或于开始的tag后加上"/"
l 表现与结构完全分离,代码中不涉及任何的表现元素,如style、font、bgColor、border等
l
到的定义,应遵循从大到小的原则,体现文档的结构,并有利于搜索引擎的查询。
l 给每一个表格和表单加上一个唯一的、结构标记id
l 给重要的区块加上注释,如:
l 给图片加上alt标签
l 所有的标签必须进行合理的嵌套
l 根元素前必须有元素,宣告使用那一种DTD
l XHTML1 Transitional:
l 根元素必须有xmlns属性来指定使用http://www.w3.org/1999/xhtml的namespace
9.5 CSS编码规范
l id和class命名采用该版块的英文单词或组合命名,并第一个单词小写,第二个单词首个字母大写,如:topBar
l CSS样式表各区块用注释说明
l 尽量使用英文命名原则
l 不用加中杠和下划线
l 尽量不缩写,除非一看就明白的单词
(1)页面结构
容器: container
页头:header
内容:content/container
页面主体:main
页尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center
(2)导航
导航:nav
主导航:mainbav
子导航:subnav
顶导航:topnav
边导航:sidebar
左导航:leftsidebar
右导航:rightsidebar
菜单:menu
子菜单:submenu
标题: title
摘要: summary
(3)功能
标志:logo
广告:banner
登陆:login
登录条:loginbar
注册:regsiter
搜索:search
功能区:shop
标题:title
加入:joinus
状态:status
按钮:btn
滚动:scroll
标签页:tab
文章列表:list
提示信息:msg
当前的: current
小技巧:tips
图标: icon
注释:note
指南:guild
服务:service
热点:hot
新闻:news
下载:download
投票:vote
合作伙伴:partner
友情链接:link
版权:copyright
9.6 注释的写法
/* Footer */
内容区
/* End Footer */
以上信息来自: