处理浏览器兼容所遇到的问题总结(一)
2016-06-13 14:50
549 查看
注意:因为浏览器问题,重新定义Array.prototype.indexOf…等函数时,一定要注意符合原始定义,不要随便用别的实现方式定义,否则可能会影响插件调用
之前开发项目时,前端调试都是以google chrome浏览器为准,现需处理浏览器兼容问题,现将遇到的问题总结如下:
原因:bootstrap中添加了样式
解决方法:去掉table中的table类属性。
(2)将
替换为
无论页面是否包含 指令,均使用 Windows Internet Explorer 7 的标准渲染模式。
开启 IE8 的标准渲染模式,但由于本身 X-UA-Compatible 文件头仅支持 IE8 以上版本,因此等同于冗余代码。
Edge 模式通知 Windows Internet Explorer 以最高级别的可用模式显示内容,这实际上破坏了“锁定”模式。
参考文章:http://blog.csdn.net/xyr05288/article/details/51657706
// 由于document.documentElement.scrollTop和document.body.scrollTop在标准模式或者是奇怪模式下都只有一个会返回有效的值,所以都加上也不会有问题
(2)之后在点击事件处理完毕后,使用之前保存的位置将滑动条的位置恢复至点击时的位置。
//20160615 屏幕滑动条 回到点击圆圈按钮时的位置 如果不加此语句 统计图加载完后 屏幕滚动条会上移至顶部
处理时出现了 chrome浏览器只支持document.body.scrollTop,而IE和firefox只支持
document.documentElement.scrollTop的情况,以上的处理方法是对这三个浏览器兼容的。
详见http://blog.csdn.net/xyr05288/article/details/51680048
thymeleaf
javascript:
更改后代码
thymeleaf
@{…}链接url的表达式。
javascript:
详见http://www.blogjava.net/bjwulin/archive/2013/02/07/395234.html
后面发现:
1、eclipse中的内置浏览器实际上调用的是系统中的ie,然后我在ie中测试了一下,果然如此,和eclipse内置浏览器中显示的一样,不能删除;
2、我的ie浏览器是ie8,然而我用的jQuery确实2.0版本的,jQuery从2.0版开始不再支持IE6、IE7和IE8,这就是问题所在;
3、将jQuery版本换成2.0版本以下,问题解决。
解决方案:根据不同的浏览器加载不同版本的jquery
附带判断所用浏览器的方法:
方式一:
方式二:
解决方案:
其它浏览器是没问题的,自然不是网络问题。其实后来找出来是因为IE前面需要加”http://”才能访问,其它浏览器会默认加上这个,但IE不会
针对ie8及以下版本,自己创建indexOf函数。
http://stackoverflow.com/questions/8098406/code-with-classlist-does-not-work-in-ie
解决方案:
重写此属性
http://www.cnblogs.com/softlover/archive/2012/11/21/2781388.html
mediaquery用于实现屏幕的自适应显示,适用场景为:
默认情况下,页面容器的宽度是980px,这个尺寸优化了大于1024px的分辨率。Media query用来检查 viewport 宽度,如果小于980px他会变为窄屏显示模式,页面布局将会以流动的宽度代替固定宽度。如果 viewport 小于650px,他会变为mobile显示模式,内容、侧边栏等内容会变为单独列布局方式,他们的宽度占满屏幕宽度。
示例:
用法:
在JS中可以使用:
test.innerHTML:
也就是从对象的起始位置到终止位置的全部内容,包括Html标签。
上例中的test.innerHTML的值也就是
test.innerText:
从起始位置到终止位置的内容, 但它去除Html标签
上例中的text.innerTest的值也就是“test1 test2”, 其中span标签去除了。
test.outerHTML:
除了包含innerHTML的全部内容外, 还包含对象标签本身。
特别说明:
innerHTML是符合W3C标准的属性,而innerText只适用于IE浏览器,因此,尽可能地去使用innerHTML,而少用innerText,如果要输出不含HTML标签的内容,可以使用innerHTML取得包含HTML标签的内容后,再用正则表达式去除HTML标签,下面是一个简单的符合W3C标准的示例:
由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替。
代码如下:
针对非 input 元素,各浏览器中,既可以把对元素属性的改变写在显示元素(insertBefore 或 appendChild)之前,也可以在其后。
针对 input 元素,为了兼容 IE,type 属性写在显示元素(insertBefore 或 appendChild)之前,其它属性写在其后。
实例(兼容性)
document.createElement创建的
测试代码中避开了type的默认值,因为
解决方案
MSDN有一段说明:
As of Microsoft Internet Explorer 5, the type property is read/write-once, but only when an input element is created with the createElement method and before it is added to the document.
即只有document.createElement创建的input元素,在其增加到DOM树之前允许对type属性进行一次更改。但从实际情况来看并非如此,这个仅有的一次设置type的机会在创建时就用掉了。从上面的测试结果看,这个问题直到IE9才修复。
针对IE,document.createElement(tag)中,tag可以是带有属性的字符串,创建时即将type和name写上即可。
Attributes can be included with the sTag as long as the entire string is valid HTML.
对其他的现代浏览器(Chrome、Safari等)使用setAttribute即可,或者使用document.createAttribute创建属性节点,再通过setAttributeNode加到元素节点上。
方法一:
方法二:
使用canvas时:
(2)IE8下使用
excanvas是利用IE支持的VML对象来模拟Canvas的绘图的。
excanvas.js首先创建Canvas对象,然后把所有有关Canvas的绘图操作都用相应的VML对象来实现,所以我们在低版本的ie中也能看到Canvas图像了。
原html中代码为:
经excanvas处理后为:
因为如果在样式文件或页面文件代码中直接用display:none对元素进行了隐藏,载入页面后,在没有通过js设置样式使元素显示的前提下,使用js代码会无法正确获得该元素的一些属性,比如offSetTop,offSetLeft等,返回的值会为0,通过js设置style.display来使元素显示后才能正确获得这些值。
canvas下的div的width和height一开始被初始化为了0,即使之后divContainer的display置为了”“,canvas下的图像也无法显示。
解决方法:
先设置divContainer的display置为了”“,再对canvas画图,之后再将divContainer的display置为了”none”.
(3)如(2)中所示,由于canvas下的div,position为absolute, 所以需要将其父元素canvas的position设为relative,这样才能保证canvas下div里的图形显示在原本canvas定义的位置离里,而不是绝对的始终显示在屏幕的某一位置。
(4)IE8画实心圆时,角度要用弧度(0,Math.PI*2), 不要使用(0,360)
Rem的使用
em是相对于其父元素来设置字体大小的,这样存在一个问题,进行任何元素设置之前,都需要知道其父元素的大小,在我们多次使用时,就会带来无法预知的错误风险。
而rem是相对于根元素
例如:浏览器默认的字号16px,如下px与rem的转换关系:
| px | rem |
| 12 | 12/16 = .75 |
| 14 | 14/16 = .875 |
| 16 | 16/16 = 1 |
| 18 | 18/16 = 1.125 |
| 20 | 20/16 = 1.25 |
| 24 | 24/16 = 1.5 |
| 30 | 30/16 = 1.875 |
| 36 | 36/16 = 2.25 |
| 42 | 42/16 = 2.625 |
| 48 | 48/16 = 3 |
将css中input:checked 改为 input[checked] 即可
1. 如果坚持要使用innerHTML属性,需使用一个div元素封装select,然后设置div对象的innerHTML属性。
2. 利用option元素
关于css hack
参考:
http://blog.csdn.net/freshlover/article/details/12132801
方式一:条件注释法
这种方式是IE浏览器专有的Hack方式,微软官方推荐使用的hack方式。举例如下
方式二:类内属性前缀法
属性前缀法是在CSS样式属性名前加上一些只有特定浏览器才能识别的hack前缀,以达到预期的页面展现效果。
说明:在标准模式中
方式三:选择器前缀法
选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器,在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行hack。
目前最常见的是
demo如下
应用:
之前开发项目时,前端调试都是以google chrome浏览器为准,现需处理浏览器兼容问题,现将遇到的问题总结如下:
一. firefox 浏览器div下的table无水平滑动条
<div id="tableContainer" style="height:420px;width:100%;" class="table-responsive"> <table id="demoTable" class="table table-condensed table-bordered" style="width:1650px;">
原因:bootstrap中添加了样式
.table{max-width:100%;}
解决方法:去掉table中的table类属性。
二. IE下无法用AJAX表单上传文件
解决方法:(1)用form表单post提交上传文件(2)将
<meta http-equiv="x-ua-compatible" content="ie=7" />
替换为
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
无论页面是否包含 指令,均使用 Windows Internet Explorer 7 的标准渲染模式。
<meta http-equiv="X-UA-Compatible" content="IE=8" />
开启 IE8 的标准渲染模式,但由于本身 X-UA-Compatible 文件头仅支持 IE8 以上版本,因此等同于冗余代码。
<meta http-equiv="X-UA-Compatible" content="edge" />
Edge 模式通知 Windows Internet Explorer 以最高级别的可用模式显示内容,这实际上破坏了“锁定”模式。
参考文章:http://blog.csdn.net/xyr05288/article/details/51657706
三. 问题:当点击屏幕下方的按钮,按钮点击事件处理后,屏幕滑动条会跳回顶部,导致不能及时看到处理结果,要看到结果还是要将滑动条重新拉至下方。
解决方法:(1)在鼠标点击按钮后,先获取屏幕当前滑动条的位置// 由于document.documentElement.scrollTop和document.body.scrollTop在标准模式或者是奇怪模式下都只有一个会返回有效的值,所以都加上也不会有问题
g_beforeClickScrollTop = document.body.scrollTop + document.documentElement.scrollTop;
(2)之后在点击事件处理完毕后,使用之前保存的位置将滑动条的位置恢复至点击时的位置。
//20160615 屏幕滑动条 回到点击圆圈按钮时的位置 如果不加此语句 统计图加载完后 屏幕滚动条会上移至顶部
document.body.scrollTop = g_beforeClickScrollTop; document.documentElement.scrollTop = g_beforeClickScrollTop;
处理时出现了 chrome浏览器只支持document.body.scrollTop,而IE和firefox只支持
document.documentElement.scrollTop的情况,以上的处理方法是对这三个浏览器兼容的。
详见http://blog.csdn.net/xyr05288/article/details/51680048
四. IE浏览器在 a href中有中文参数时,显示乱码,firefox和chrome浏览器显示正常
之前代码:thymeleaf
<a th:href="${'project/aaaaaaa?id='+item.id +'&name=' + item.name }" th:text="${item.name}" title="点击进入" target="_blank">
javascript:
'<td Value="' + e.name + '"><a href="/project/aaaaaa?id=' + e.id + '&name=' + e.name + '" title="点击进入项目雷达" target="_blank">' + e.name + '</a></td>'
更改后代码
thymeleaf
<a th:href="@{project/aaaaaaa(id = ${item.id}, name = ${item.name})}" th:text="${item.name}" title="点击进入" target="_blank">
@{…}链接url的表达式。
th:href="@{/xxx/aa.do(id=${o.id})",会自动进行url-encoding的处理。@{…}内部可以是需要计算的表达式,比如:
th:href=”@{'/details/'+${user.login}(orderId=${o.id})}"
javascript:
'<td Value="' + e.name + '"><a href="/project/aaaaaa?id=' + e.id + '&name=' + encodeURI(e.name) + '" title="点击进入项目雷达" target="_blank">' + e.name + '</a></td>'
详见http://www.blogjava.net/bjwulin/archive/2013/02/07/395234.html
五. IE浏览器无法识别jquery的$对象
原因: 今天在用jQuery实现web上面的一个删除功能的时候,发现通过chrome删除完全正常,但是在eclipse的内置浏览器中却不能删除,感觉有些莫名其妙,找了半天原因。后面发现:
1、eclipse中的内置浏览器实际上调用的是系统中的ie,然后我在ie中测试了一下,果然如此,和eclipse内置浏览器中显示的一样,不能删除;
2、我的ie浏览器是ie8,然而我用的jQuery确实2.0版本的,jQuery从2.0版开始不再支持IE6、IE7和IE8,这就是问题所在;
3、将jQuery版本换成2.0版本以下,问题解决。
解决方案:根据不同的浏览器加载不同版本的jquery
//方式一 <!--[if !IE]><!--> <script src="../../static/jquery/2.1.4/jquery-2.1.4.min.js" th:src="@{/jquery/2.1.4/jquery-2.1.4.min.js}"></script> <!--<![endif]--> <!--[if IE]><!--> <script src="../../static/jquery/1.11.0/jquery-1.11.0.min.js" th:src="@{/jquery/1.11.0/jquery-1.11.0.min.js}"></script> <!--<![endif]--> //方式二 <script language="javascript"> if(navigator.appName == "Microsoft Internet Explorer") { if(navigator.appVersion.match(/7./i)=='7.') { //是IE7,不加载dojo.js }else{ //加载dojo.js document.write("<script src=\"dojo.js\">"+"</scr"+"ipt>"); } } </script> 把上面这段js放到你引用dojo.js的地方就ok了
附带判断所用浏览器的方法:
方式一:
<!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![endif]--> <!--[if IE 6]> 仅IE6可识别 <![endif]--> <!--[if lt IE 6]> IE6以及IE6以下版本可识别 <![endif]--> <!--[if gte IE 6]> IE6以及IE6以上版本可识别 <![endif]--> <!--[if IE 7]> 仅IE7可识别 <![endif]--> <!--[if lt IE 7]> IE7以及IE7以下版本可识别 <![endif]--> <!--[if gte IE 7]> IE7以及IE7以上版本可识别 <![endif]--> <!--[if IE 8]> 仅IE8可识别 <![endif]--> <!--[if IE 9]> 仅IE9可识别 <![endif]-->
方式二:
1、判断浏览器是否为IE document.all ? 'IE' : 'others':在IE下document.all值为1,而其他浏览器下的值为0; navigator.userAgent.indexOf("MSIE")>0 ? 'IE' : 'others':navigator.userAgent是描述用户代理信息。 navigator.appName.indexOf("Microsoft") != -1 ? 'IE' : 'others':navigator.appName描述浏览器名称信息。 2、判断IE版本 navigator.appVersion.match(/6./i)=="6." ? 'IE6' : 'other version':在已知是IE浏览器的情况下,可以通过此方法判断是否是IE6; navigator.userAgent.indexOf("MSIE 6.0")>0 ? 'IE7' : 'other version':同上; navigator.appVersion.match(/7./i)=="7." ? 'IE7' : 'other version':在已知是IE浏览器的情况下,可以通过此方法判断是否是IE7; navigator.userAgent.indexOf("MSIE 7.0")>0 ? 'IE7' : 'other version':同上; navigator.appVersion.match(/8./i)=="8." ? 'IE8' : 'other version':在已知是IE浏览器的情况下,可以通过此方法判断是否是IE8; navigator.userAgent.indexOf("MSIE 8.0")>0 ? 'IE8' : 'other version':同上。
六. 将web应用地址粘贴到IE地址栏中无法打开
解决方案:
其它浏览器是没问题的,自然不是网络问题。其实后来找出来是因为IE前面需要加”http://”才能访问,其它浏览器会默认加上这个,但IE不会
七. IE8不识别javascript的Array.indexOf方法
解决方案针对ie8及以下版本,自己创建indexOf函数。
//20161123 add 针对IE不支持indexOf的问题添加 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { var k; if (this == null) { throw new TypeError('"this" is null or not defined'); } var O = Object(this); var len = O.length >>> 0; if (len === 0) { return -1; } var n = +fromIndex || 0; if (Math.abs(n) === Infinity) { n = 0; } if (n >= len) { return -1; } k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); while (k < len) { if (k in O && O[k] === searchElement) { return k; } k++; } return -1; };//indexOf }
八. IE8不识别侧边隐藏栏插件BootSideMenu.js中的DOM元素的classList属性
参考文章:http://stackoverflow.com/questions/8098406/code-with-classlist-does-not-work-in-ie
解决方案:
重写此属性
//20161123 add 针对IE不支持indexOf的问题添加 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { var k; if (this == null) { throw new TypeError('"this" is null or not defined'); } var O = Object(this); var len = O.length >>> 0; if (len === 0) { return -1; } var n = +fromIndex || 0; if (Math.abs(n) === Infinity) { n = 0; } if (n >= len) { return -1; } k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); while (k < len) { if (k in O && O[k] === searchElement) { return k; } k++; } return -1; };//indexOf }
//20161123 为解决IE无法获取classList属性的问题 添加此函数 重写classList
Object.defineProperty(Element.prototype, 'classList', {
get: function() {
var self = this, bValue = self.className.split(" ")
bValue.add = function (){
var b;
for(i in arguments){
b = true;
for (var j = 0; j<bValue.length;j++)
if (bValue[j] == arguments[i]){
b = false
break
}
if(b)
self.className += (self.className?" ":"")+arguments[i]
}
}
bValue.remove = function(){
self.className = ""
for(i in arguments)
for (var j = 0; j<bValue.length;j++)
if(bValue[j] != arguments[i])
self.className += (self.className?" " :"")+bValue[j]
}
bValue.toggle = function(x){
var b;
if(x){
self.className = ""
b = false;
for (var j = 0; j<bValue.length;j++)
if(bValue[j] != x){
self.className += (self.className?" " :"")+bValue[j]
b = false
} else b = true
if(!b)
self.className += (self.className?" ":"")+x
} else throw new TypeError("Failed to execute 'toggle': 1 argument required")
return !b;
}
bValue.contains = function(value) {
return !!~self.className.split(/\s+/g).indexOf(value);
}
return bValue;
},
enumerable: false
});
九. IE8和之前的浏览器不支持CSS3 media queries,你可以在页面中添加css3-mediaqueries.js来解决这个问题。
参考文章:http://www.cnblogs.com/softlover/archive/2012/11/21/2781388.html
<!--[if lt IE 9]> <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]-->
mediaquery用于实现屏幕的自适应显示,适用场景为:
默认情况下,页面容器的宽度是980px,这个尺寸优化了大于1024px的分辨率。Media query用来检查 viewport 宽度,如果小于980px他会变为窄屏显示模式,页面布局将会以流动的宽度代替固定宽度。如果 viewport 小于650px,他会变为mobile显示模式,内容、侧边栏等内容会变为单独列布局方式,他们的宽度占满屏幕宽度。
示例:
@media screen and (max-width: 980px) { #pagewrap { width: 95%; } #content { width: 60%; padding: 3% 4%; } #sidebar { width: 30%; } #sidebar .widget { padding: 8% 7%; margin-bottom: 10px; } } @media screen and (max-width: 650px) { #header { height: auto; } #searchform { position: absolute; top: 5px; right: 0; } #main-nav { position: static; } #site-logo { margin: 15px 100px 5px 0; position: static; } #site-description { margin: 0 0 15px; position: static; } #content { width: auto; float: none; margin: 20px 0; } #sidebar { width: 100%; float: none; margin: 0; } }
十. js中innerHTML与innerText的用法与区别
参考:http://blog.csdn.net/yttcjj/article/details/7288414用法:
<div id="test"> <span style="color:red">test1</span> test2 </div>
在JS中可以使用:
test.innerHTML:
也就是从对象的起始位置到终止位置的全部内容,包括Html标签。
上例中的test.innerHTML的值也就是
“<span style="color:red">test1</span> test2 ”。
test.innerText:
从起始位置到终止位置的内容, 但它去除Html标签
上例中的text.innerTest的值也就是“test1 test2”, 其中span标签去除了。
test.outerHTML:
除了包含innerHTML的全部内容外, 还包含对象标签本身。
<div id="test"><span style="color:red">test1</span> test2</div>
特别说明:
innerHTML是符合W3C标准的属性,而innerText只适用于IE浏览器,因此,尽可能地去使用innerHTML,而少用innerText,如果要输出不含HTML标签的内容,可以使用innerHTML取得包含HTML标签的内容后,再用正则表达式去除HTML标签,下面是一个简单的符合W3C标准的示例:
<a href="javascript:alert(document.getElementById('test').innerHTML.replace(/<.+?>/gim,''))">无HTML,符合W3C标准</a>
由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替。
十一. IE8不支持js中动态创建button后,再通过btnObj.type设置type属性时
后来通过参考http://www.111cn.net/wy/js-ajax/49381.htm中的文章找到了解决方法。代码如下:
var btnObj = document.createElement("button"); //btnObj.type="button"; //IE不支持type if(!btnObj){ btnObj.setAttribute('type', 'button'); }
针对非 input 元素,各浏览器中,既可以把对元素属性的改变写在显示元素(insertBefore 或 appendChild)之前,也可以在其后。
针对 input 元素,为了兼容 IE,type 属性写在显示元素(insertBefore 或 appendChild)之前,其它属性写在其后。
实例(兼容性)
document.createElement创建的
<button>的type属性为只读
测试代码中避开了type的默认值,因为
<button>的type属性在IE下的默认值是button,而在其他浏览器默认是submit 。我们平时在使用时,建议显式的声明type属性。
// 创建input var iptEl = document.createElement('input'); iptEl.type = 'password'; // 避免默认值 iptEl.name = 'damon'; document.body.appendChild(iptEl); // 创建button var btnEl = document.createElement('button'); btnEl.type = 'reset'; // IE下这里报错了 btnEl.name = 'damon'; document.body.appendChild(btnEl); alert(document.getElementsByTagName('input')[0].type +','+ document.getElementsByTagName('button')[0].type);
解决方案
MSDN有一段说明:
As of Microsoft Internet Explorer 5, the type property is read/write-once, but only when an input element is created with the createElement method and before it is added to the document.
即只有document.createElement创建的input元素,在其增加到DOM树之前允许对type属性进行一次更改。但从实际情况来看并非如此,这个仅有的一次设置type的机会在创建时就用掉了。从上面的测试结果看,这个问题直到IE9才修复。
针对IE,document.createElement(tag)中,tag可以是带有属性的字符串,创建时即将type和name写上即可。
Attributes can be included with the sTag as long as the entire string is valid HTML.
对其他的现代浏览器(Chrome、Safari等)使用setAttribute即可,或者使用document.createAttribute创建属性节点,再通过setAttributeNode加到元素节点上。
方法一:
var btnEl; try { btnEl = document.createElement('<BUTTON name=damon type=reset></BUTTON>'); } catch(e){} if(! btnEl) { btnEl = document.createElement('button'); btnEl.setAttribute('type', 'reset'); btnEl.setAttribute('name', 'damon'); } document.body.appendChild(btnEl); alert(document.getElementsByTagName('button')[0].type +','+ document.getElementsByTagName('button')[0].name);
方法二:
var btnEl; try { btnEl = document.createElement('<BUTTON name=damon type=reset></BUTTON>'); } catch(e){} if(! btnEl) { btnEl = document.createElement('button'); var aType = document.createAttribute('type'); var aName = document.createAttribute('name'); aType.value = 'reset'; aName.value = 'damon'; btnEl.setAttributeNode(aType); btnEl.setAttributeNode(aName); } document.body.appendChild(btnEl); alert(document.getElementsByTagName('button')[0].type +','+ document.getElementsByTagName('button')[0].name);
十二. IE8不支持html5 canvas
(1)针对IE8不支持html5 canvas的功能需要在html文件head中添加js文件:<!-- 针对IE浏览器不兼容canvas的情况 --> <!--[if IE]><!--> <script src="/explorerCanvas/excanvas.js"></script> <script src="/explorerCanvas/html5shiv.js"></script> <!--<![endif]-->
使用canvas时:
var canvas=document.getElementById(canvasEleId); //针对IE浏览器不兼容canvas的情况 //var cxt=canvas.getContext("2d"); var cxt=null; if (typeof window.G_vmlCanvasManager!="undefined") { canvas = window.G_vmlCanvasManager.initElement(canvas); cxt=canvas.getContext("2d"); }else { cxt=canvas.getContext("2d"); }
(2)IE8下使用
display:none样式隐藏的div里的canvas,不显示所画图形,原因是:
excanvas是利用IE支持的VML对象来模拟Canvas的绘图的。
excanvas.js首先创建Canvas对象,然后把所有有关Canvas的绘图操作都用相应的VML对象来实现,所以我们在低版本的ie中也能看到Canvas图像了。
原html中代码为:
<div id="divContainer" style="display: none;"> <canvas class="myCanvasCls" id="mycanvas" width="30" height="30"></canvas> </div>
经excanvas处理后为:
<div id="divContainer" style="display: none;"> <canvas class="myCanvasCls" id="mycanvas" style="width: 30px; height: 30px;" height="30" width="30" getContext="function getContext() { return this.context_ || (this.context_ = new CanvasRenderingContext2D_(this));}" context_="[object Object]"> <div style="position: absolute; width: 0px; height: 0px; overflow: hidden;"> <g_vml_:shape style="position: absolute; width: 10px; height: 10px;"> <g_vml_:fill/> </div> <div style="position: absolute; filter: alpha(opacity=0); BACKGROUND-COLOR: red; width: 0px; height: 0px; overflow: hidden;"/> </canvas> </div>
因为如果在样式文件或页面文件代码中直接用display:none对元素进行了隐藏,载入页面后,在没有通过js设置样式使元素显示的前提下,使用js代码会无法正确获得该元素的一些属性,比如offSetTop,offSetLeft等,返回的值会为0,通过js设置style.display来使元素显示后才能正确获得这些值。
canvas下的div的width和height一开始被初始化为了0,即使之后divContainer的display置为了”“,canvas下的图像也无法显示。
解决方法:
先设置divContainer的display置为了”“,再对canvas画图,之后再将divContainer的display置为了”none”.
(3)如(2)中所示,由于canvas下的div,position为absolute, 所以需要将其父元素canvas的position设为relative,这样才能保证canvas下div里的图形显示在原本canvas定义的位置离里,而不是绝对的始终显示在屏幕的某一位置。
(4)IE8画实心圆时,角度要用弧度(0,Math.PI*2), 不要使用(0,360)
var canvas=document.getElementById(canvasId); //针对IE浏览器不兼容canvas的情况 //var cxt=canvas.getContext("2d"); var cxt=null; if (typeof window.G_vmlCanvasManager!="undefined") { canvas=window.G_vmlCanvasManager.initElement(canvas); cxt=canvas.getContext("2d"); }else { cxt=canvas.getContext("2d"); } //alert("cxt: " + cxt + "; Math.PI*2: " + Math.PI*2); //画一个实心圆 cxt.beginPath(); cxt.fillStyle="#ddd";//填充颜色,默认是黑色 /*arc(x, y, radius, startAngle, endAngle, counterclockwise) x,y是中心点坐标 counterclockwise弧沿着圆周的逆时针方向(TRUE)还是顺时针方向(FALSE)遍历。*/ cxt.arc(15,15,10,0,Math.PI*2,false); cxt.closePath(); cxt.fill();//画实心圆
十三. IE8不支持rem,不支持input:checked选择器
rem是CSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位。不同的是em是相对于元素的父元素的font-size进行计算;rem是相对于根元素html的font-size进行计算。这样一来rem就绕开了复杂的层级关系,实现了类似于em单位的功能。Rem的使用
em是相对于其父元素来设置字体大小的,这样存在一个问题,进行任何元素设置之前,都需要知道其父元素的大小,在我们多次使用时,就会带来无法预知的错误风险。
而rem是相对于根元素
<html>,这样就意味着,我们只需要在根元素确定一个参考值,这个参考值设置为多少,完全可以根据需求来定。
例如:浏览器默认的字号16px,如下px与rem的转换关系:
| px | rem |
| 12 | 12/16 = .75 |
| 14 | 14/16 = .875 |
| 16 | 16/16 = 1 |
| 18 | 18/16 = 1.125 |
| 20 | 20/16 = 1.25 |
| 24 | 24/16 = 1.5 |
| 30 | 30/16 = 1.875 |
| 36 | 36/16 = 2.25 |
| 42 | 42/16 = 2.625 |
| 48 | 48/16 = 3 |
将css中input:checked 改为 input[checked] 即可
十四. IE浏览器不支持修改select元素的innerHTML属性
解决方法(参考文章):1. 如果坚持要使用innerHTML属性,需使用一个div元素封装select,然后设置div对象的innerHTML属性。
2. 利用option元素
<html> <head> <title>Example</title> <script type="text/javascript"> <!-- function fill_select1() { for ( var i = 0; i < 100; i++) { select1.options[i] = new Option(i, i); } } function fill_select2() { var sOpts = "<select>"; for ( var i = 0; i < 100; i++) { sOpts += '<option value="' + i + '">' + i + '</option>'; } select2.outerHTML = sOpts + "</option>"; } function fill_select3() { for ( var i = 0; i < 100; i++) { var oOption = document.createElement("OPTION"); oOption.text = "Option: " + i; oOption.value = i; document.all.select3.add(oOption) } } //--> </script> </head> <body> <h2> SELECT Box Population </h2> <select id=select1 name=select1></select> <input type="button" value="Populate with options list" id="button1" name="button1" onclick="fill_select1();"> <br /> <br /> <select id="select2" name="select2"></select> <INPUT type="button" value="Populate with outerHTML" id="button2" name="button2" onclick="fill_select2();"> <br /> <br /> <select id="select3" name="select3"></select> <input type="button" value="Populate with using createElement" id="button3" name="button3" onclick="fill_select3();"> </body> </html>
十五 css hack
弹性布局flex对IE8不兼容,用css hack解决body{ margin: 0; height: 100%; background: #bfd1e1; font-size:13px; font-family: 微软雅黑; display: flex; justify-content: center; align-items: center; display: -webkit-flex; -webkit-justify-content: center; -webkit-align-items: center; /* \0 IE8/IE9/IE10都生效,是IE8/9/10的hack*/ position:absolute\0; top:20%\0; left:32%\0; }
关于css hack
参考:
http://blog.csdn.net/freshlover/article/details/12132801
方式一:条件注释法
这种方式是IE浏览器专有的Hack方式,微软官方推荐使用的hack方式。举例如下
只在IE下生效 <!--[if IE]> 这段文字只在IE浏览器显示 <![endif]--> 只在IE6下生效 <!--[if IE 6]> 这段文字只在IE6浏览器显示 <![endif]--> 只在IE6以上版本生效 <!--[if gte IE 6]> 这段文字只在IE6以上(包括)版本IE浏览器显示 <![endif]--> 只在IE8上不生效 <!--[if ! IE 8]> 这段文字在非IE8浏览器显示 <![endif]--> 非IE浏览器生效 <!--[if !IE]> 这段文字只在非IE浏览器显示 <![endif]-->
方式二:类内属性前缀法
属性前缀法是在CSS样式属性名前加上一些只有特定浏览器才能识别的hack前缀,以达到预期的页面展现效果。
说明:在标准模式中
"-"减号是IE6专有的hack "\9" IE6/IE7/IE8/IE9/IE10都生效 "\0" IE8/IE9/IE10都生效,是IE8/9/10的hack "\9\0" 只对IE9/IE10生效,是IE9/10的hack
方式三:选择器前缀法
选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器,在CSS选择器前加上一些只有某些特定浏览器才能识别的前缀进行hack。
目前最常见的是
*html *前缀只对IE6生效 *+html *+前缀只对IE7生效 @media screen\9{...}只对IE6/7生效 @media \0screen {body { background: red; }}只对IE8有效 @media \0screen\,screen\9{body { background: blue; }}只对IE6/7/8有效 @media screen\0 {body { background: green; }} 只对IE8/9/10有效 @media screen and (min-width:0\0) {body { background: gray; }} 只对IE9/10有效 @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {body { background: orange; }} 只对IE10有效等等
demo如下
<script type="text/javascript"> //alert(document.compatMode); </script> <style type="text/css"> body:nth-of-type(1) .iehack{ color: #F00;/* 对Windows IE9/Firefox 7+/Opera 10+/所有Chrome/Safari的CSS hack ,选择器也适用几乎全部Mobile/Linux/Mac browser*/ } .demo1,.demo2,.demo3,.demo4{ width:100px; height:100px; } .hack{ /*demo1 */ /*demo1 注意顺序,否则IE6/7下可能无法正确显示,导致结果显示为白色背景*/ background-color:red; /* All browsers */ background-color:blue !important;/* All browsers but IE6 */ *background-color:black; /* IE6, IE7 */ +background-color:yellow;/* IE6, IE7*/ background-color:gray\9; /* IE6, IE7, IE8, IE9, IE10 */ background-color:purple\0; /* IE8, IE9, IE10 */ background-color:orange\9\0;/*IE9, IE10*/ _background-color:green; /* Only works in IE6 */ *+background-color:pink; /* WARNING: Only works in IE7 ? Is it right? */ } /*可以通过javascript检测IE10,然后给IE10的<html>标签加上class=”ie10″ 这个类 */ .ie10 #hack{ color:red; /* Only works in IE10 */ } /*demo2*/ .iehack{ /*该demo实例是用于区分标准模式下ie6~ie9和Firefox/Chrome的hack,注意顺序 IE6显示为:绿色, IE7显示为:黑色, IE8显示为:红色, IE9显示为:蓝色, Firefox/Chrome显示为:橘色, (本例IE10效果同IE9,Opera最新版效果同IE8) */ background-color:orange; /* all - for Firefox/Chrome */ background-color:red\0; /* ie 8/9/10/Opera - for ie8/ie10/Opera */ background-color:blue\9\0; /* ie 9/10 - for ie9/10 */ *background-color:black; /* ie 6/7 - for ie7 */ _background-color:green; /* ie 6 - for ie6 */ } /*demo3 实例是用于区分标准模式下ie6~ie9和Firefox/Chrome的hack,注意顺序 IE6显示为:红色, IE7显示为:蓝色, IE8显示为:绿色, IE9显示为:粉色, Firefox/Chrome显示为:橘色, (本例IE10效果同IE9,Opera最新版效果也同IE9为粉色) */ .element { background-color:orange; /* all IE/FF/CH/OP*/ } .element { *background-color: blue; /* IE6+7, doesn't work in IE8/9 as IE7 */ } .element { _background-color: red; /* IE6 */ } .element { background-color: green\0; /* IE8+9+10 */ } :root .element { background-color:pink\0; } /* IE9+10 */ /*demo4*/ /* 该实例是用于区分标准模式下ie6~ie10和Opera/Firefox/Chrome的hack,本例特别要注意顺序 IE6显示为:橘色, IE7显示为:粉色, IE8显示为:黄色, IE9显示为:紫色, IE10显示为:绿色, Firefox显示为:蓝色, Opera显示为:黑色, Safari/Chrome显示为:灰色, */ .hacktest{ background-color:blue; /* 都识别,此处针对firefox */ background-color:red\9; /*all ie*/ background-color:yellow\0; /*for IE8/IE9/10 最新版opera也认识*/ +background-color:pink; /*for ie6/7*/ _background-color:orange; /*for ie6*/ } @media screen and (min-width:0){ .hacktest {background-color:black\0;} /*opera*/ } @media screen and (min-width:0) { .hacktest { background-color:purple\9; }/* for IE9/IE10 PS:国外有些习惯常写作\0,根本没考虑Opera也认识\0的实际 */ } @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { .hacktest { background-color:green; } /* for IE10+ 此写法可以适配到高对比度和默认模式,故可覆盖所有ie10的模式 */ } @media screen and (-webkit-min-device-pixel-ratio:0){ .hacktest {background-color:gray;} } /*for Chrome/Safari*/ /* #963棕色 :root is for IE9/IE10, 优先级高于@media, 慎用!如果二者合用,必要时在@media样式加入 !important 才能区分IE9和IE10 */ /* :root .hacktest { background-color:#963\9; } */ </style>
十六 CSS3 线性渐变(linear-gradient) 兼容IE8,IE9
参考:http://www.mamicode.com/info-detail-173300.html/* 共有三个参数,第一个参数表示线性渐变的方向,top 是从上到下、left 是从左到右,如果定义成 left top,那就是从左上角到右下角。第二个和第三个参数分别是起点颜色和终点颜色。你还可以在它们之间插入更多的参数,表示多种颜色的渐变 */ -moz-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* ) -webkit-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* ) -o-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* ) /* 线性渐变在 Trident (IE) 下的应用 IE依靠滤镜实现渐变。startColorstr表示起点的颜色,endColorstr 表示终点颜色。GradientType 表示渐变类型,0 为缺省值,表示垂直渐变,1 表示水平渐变。 */ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB);/*IE<9>*/ -ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB)";/*IE8+*/
应用:
<span style="font-size:24px;">body{ width:100%; height:200px; background: -webkit-gradient(linear, 0 0, 0 0, from(#F6F4EF), to(#F1EDE6)); background: -webkit-linear-gradient(left,#F1EDE6, #F6F4EF, #F1EDE6); background: -moz-linear-gradient(left,#F1EDE6, #F6F4EF, #F1EDE6); background: -o-linear-gradient(left,#F1EDE6, #F6F4EF, #F1EDE6); background: -ms-linear-gradient(left,#F1EDE6, #F6F4EF, #F1EDE6); background: linear-gradient(left,#F1EDE6, #F6F4EF, #F1EDE6); filter: progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr = #F6F4EF, endColorstr = #F1EDE6); } </span>
相关文章推荐
- Android Manifest 用法
- Android学习笔记(二九):嵌入浏览器
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 回顾 Firefox 历史
- 小白观察:微软释放出其基于 Chromium 的 Edge 浏览器
- 浏览器 cookie 限制
- 玩转浏览器IE7的5个顶级使用技巧
- 字符集导致的浏览器跨站脚本攻击分析
- 更改IE浏览器的图标
- 如何创建ajax对象并兼容多个浏览器
- css ie6 ie7 ff的CSS hack使用技巧
- CSS 浏览器的等宽空格问题解决
- 区分IE6,IE7,firefox的CSS hack
- PHP检测用户是否关闭浏览器的方法
- PHP限制页面只能在微信自带浏览器访问的代码
- asp.net实现获取客户端详细信息
- ASP.NET实现推送文件到浏览器的方法
- 多种浏览器清除缓存的方法小结
- Dom与浏览器兼容性说明