如何解决浏览器兼容性问题
手机端和电脑端兼容
百分比法
CSS中的百分比中指的是相对于父元素的宽度。子元素的padding-left:50%,父元素的宽度是百,子元素的margin-top:20%,那么父元素的高是百。body默认宽度是屏幕宽度(PC中指的是浏览器宽度)子孙元素按百分比定位(或指定尺寸)就可以了。但这只适合布局简单的页面,复杂的页面实现很困难。
使用CSS3单位rem
在页面载入开始时首先判断window的宽度(是window的宽度($(window).width()),不是屏幕分辩率的宽度(screen.width),两者差别请自行查阅),假设宽度为W,一个div在宽度为640px的设计稿的下的宽度为dW1,如果html的font-size为100px,那么这个div的宽度用rem表示是多少呢?
计算:div宽度dW2=dW1/100,px与rem之间换算除以100就可以,这是假定屏幕宽度为640的,而不同宽度的屏幕怎么处理,为了能保证换算容易那就要为html设置一个合适的font-size,计算:100 / 640 = fontSize / W, fontSize = W / 640 * 100 = W / 6.4。大多数浏览器font-size的最小值为12px,所以只能用100作为缩放比例。
所以会在头部加上这个JS代码:
<meta name="viewport" content="width=device-width, initial-scale=1.0,
minimum-scale=1.0,maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no" />
<meta name="format-detection" content="email=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
媒体查询
媒体查询正是为解决网页适应手机屏幕。媒体查询的功能就是为不同的“媒体”设置不同的css样式,页面尺寸,设备屏幕尺寸等。
JavaScript部分
1.HTML对象获取问题
标准浏览器是由外至内,而IE是由内到外,但是最后的结果是将IE的标准定为标准。
FireFox:document.getElementById(“idName”);
ie:document.idname或者document.getElementById(“idName”).
解决办法:统一使用document.getElementById(“idName”);
event属性
我们常说的事件处理时的event属性,在标准浏览器其是传入的,IE下由window.event获取的。IE下,event对象有x,y属性,但是没有pageX,pageY属性; Firefox下,event对象有pageX,pageY属性,但是没有x,y属性。
解决方法:使用mX(mX = event.x ? event.x : event.pageX;)来代替IE下的event.x或者Firefox下的event.pageX.
event事件问题:
document.onclick=function(ev){//谷歌火狐的写法,IE9以上支持,往下不支持;
var e=ev;
console.log(e);
}
document.onclick=function(){//谷歌和IE支持,火狐不支持;
var e=event;
console.log(e);
}
document.onclick=function(ev){//兼容写法;
var e=ev||window.event;
var mouseX=e.clientX;//鼠标X轴的坐标
var mouseY=e.clientY;//鼠标Y轴的坐标
}
日期处理函数
在低版本的IE中获取的日期处理函数的值不是与1900的差值,但是在高版本的IE中和标准浏览器保持了一致,获取的值也是与1900的差值。
获得DOM节点的方式不同
其他浏览器:parentNode parentNode.childNodes
IE:parentElement parentElement.children
解决办法是:htmlshim框架可以让低于IE9的浏览器支持html5
//DOM节点相关,主要兼容IE 6 7 8
function nextnode(obj){//获取下一个兄弟节点
if (obj.nextElementSibling) {
return obj.nextElementSibling;
} else{
return obj.nextSibling;
};
}
function prenode(obj){//获取上一个兄弟节点
if (obj.previousElementSibling) {
return obj.previousElementSibling;
} else{
return obj.previousSibling;
};
}
function firstnode(obj){//获取第一个子节点
if (obj.firstElementChild) {
return obj.firstElementChild;//非IE678支持
} else{
return obj.firstChild;//IE678支持
};
}
function lastnode(obj){//获取最后一个子节点
if (obj.lastElementChild) {
return obj.lastElementChild;//非IE678支持
} else{
return obj.lastChild;//IE678支持
};
}
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下,可以使用 () 或 [] 获取集合类对象;Firefox下,只能使用 [ ]获取集合类对象。
解决方法:统一使用 [] 获取集合类对象。
自定义属性问题
问题说明:IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute() 获取自定义属性;Firefox下,只能使用getAttribute() 获取自定义属性。
解决方法:统一通过getAttribute() 获取自定义属性。
input.type属性问题
问题说明:IE下input.type属性为只读;但是Firefox下input.type属性为读写。
解决办法:不修改input.type属性。如果必须要修改,可以先隐藏原来的input,然后在同样的位置再插入一个新的input元素。
body载入问题
问题说明:Firefox的body对象在body标签没有被浏览器完全读入之前就存在;而IE的body对象则必须在body标签被浏览器完全读入之后才存在。
IE6、Opera9以及FireFox2中不存在上述问题,单纯的JS脚本可以访问在脚本之前已经载入的所有对象和元素,即使这个元素还没有载入完成。
事件委托方法
问题说明:IE下,使用document.body.onload = inject; 其中function inject()在这之前已被实现;在Firefox下,使用document.body.onload = inject().
解决方法:统一使用document.body.οnlοad=new Function(’inject()’); 或者document.body.onload = function(){/* 代码 */}.
阻止事件传播
var btn = document.getElementById("btn");
document.onclick = function() {
alert("点击了空白处")
}
btn.onclick = function(event) {
alert("点击了按钮")
var event = event || window.event;
if(event && event.stopPropagation)
{
event.stopPropagation(); // w3c 标准
}
else
{
event.cancelBubble = true; // ie 678 ie浏览器
}
}
阻止默认事件
//js阻止默认事件
document.onclick=function(e){
var e=e||window.event;
if (e.preventDefault) {
e.preventDefault();//W3C标准
}else{
e.returnValue='false';//IE..
}
}
HTML和CSS部分
html5的新标签
最突出也是最容易想到的就是高版本的浏览器用了低版本的浏览器无法识别的元素,从而导致不能解析。这点主要体现在html5的新标签上
解决办法:htmlshim框架可以让低于IE9的浏览器支持html5
ul和ol列表缩进问题
消除ul、ol等列表的缩进时,样式应写成:list-style:none;margin:0px;padding:0px.
在IE中,设置margin:0px可以去除列表的上下左右缩进、空白以及列表编号或圆点,设置padding对样式没有影响;在 Firefox 中,设置margin:0px仅仅可以去除上下的空白,设置padding:0px后仅仅可以去掉左右缩进,还必须设置list- style:none才能去除列表编号或圆点。也就是说,在IE中仅仅设置margin:0px即可达到最终效果,而在Firefox中必须同时设置margin:0px、 padding:0px以及list-style:none三项才能达到最终效果。
IE与宽度和高度的问题
IE不认得min-这个定义,但实际上它把正常的width和height当作有min的情况来使。这样问题就大了,如果只用宽度和高度,正常的浏览器里这两个值就不会变,如果只用min-width和min-height的话,IE下面根本等于没有设置宽度和高度。
{
background:#ccc;
min-height:100px;
height:auto !important;
height:100px;
overflow:visible;
}
常用的css hack
/*第一种*/
.title{ height:200px;
*height:200px;
_height:200px; }
/*第二种*/
.title{ height:200px;
*height:200px !important;
*height:200px; }
/*第三种*/
.title{ height:200px; }
*html.title{ height:200px;}
*+html.title{ height:200px;}
IE6下图片下有空隙产生
改变html的排版,或者设置img为display:block或者设置vertical-align属性为vertical-align:top/bottom/middle/text-bottom .
由于浮动引起的无法识别父盒子高度问题
解决方案:5种清除浮动的方法
清除浮动方法1:给浮动的元素的祖先元素加高度。有高度的盒子,才能关住浮动。
清除浮动方法2:clear:both;但是有致命缺陷,margin失效。
清除浮动方法3:隔墙法。在两个浮动的div间增加一个空div,就像一个屏障隔开了2个浮动,使两个浮动间互不影响。缺点: 额外增加了很多的标签,对页面结构及其的不好。
清除浮动方法4:overflow:hidden;zoom:1;
缺点: 里面尽肯能的不能有定位。 如果有定位,可能会切掉一部分。
清除浮动方法5:利用after伪类清除浮动
.clearfix:after{
content:""; 内容
visibility:hidden; 隐藏
height:0; 高度一定是0
display:block; 转换
clear:both; 清除浮动
}
.clearfix{
zoom:1; 为了照顾ie6
}
谁清除浮动,谁引用。
行内块元素之间空白缝隙的问题
(1.)利用margin 负值,例如Margin-left:-8px;
(2.)把行内块写到一行上去。
(3.)给父盒子加:font-size:0;
(4.)利用js来清除缝隙。