浏览器兼容性之JavaScript篇
近期公司职务变动,我大部分工作时间都在做web前端开发。工作性质主要是跟javascript和css(层叠样式表)打交道,而JavaScript兼容性一直是Web开发者的心病,当然我也不例外,虽然我大学时自己也试着搞过几个网站,但当时才疏学浅兼容性这方面的功能根本没有考虑过,导致开发出来的网站在不同浏览器下其形怪异,各种异常,不仅用户不满意,连自己也有点羞愧自己的技术不到位。现在有了这些意识加上行动,问题就会得到解决,在这里总结一些在开发过程中遇到的问题及解决方法,记录到博客园方便自己以后查阅,说不定还能帮助到其他初学者,何乐而不为呢。
JavaScript兼容性主要包括函数和方法差异、样式访问和设置、DOM方法及对象引用,以下就针对这几方面来总结。
一、Dom节点的删除问题
1.IE浏览器下的删除方法:
function removeNode(n) {
if (n && n.tagName != 'BODY') {
var d = document.createElement('div');
d.appendChild(n);
d.innerHTML = '';
d = null;
}
}
2.非IE浏览器下的删除方法:
function removeNode(n) {
if (n && n.parentNode && n.tagName != 'BODY') {
n.parentNode.removeChild(n);
}
}
二、日期问题
1.getYear()方法
var year=newDate().getYear(); document.write(year);
在IE10以下浏览器得到的日期是"2013",在非IE内核的浏览器中看到的日期是"113",主要是因为其他非IE内核的浏览器里面getYear返回的是"当前年份-1900"的值。
有关ECMA标准的详细资讯,请参考该网址: http://www.ecma.ch/stand/ecma-262.htm
【解决方法】
var year=newDate().getFullYear(); document.write(year);
【参考】http://blog.darkthread.net/post-2011-12-13-js-getyear-in-ie.aspx
三、对象宽高赋值问题
统一使用dom.style.height= 200+‘px’;
注意:为了兼容所有浏览器,必须加单位‘px’;
四、IE8以下浏览器Dom的重绘问题
该问题没有在网上找到相关的资料,我也是在多次尝试中才解决的,问题的现象就是一个table表格里面存放着几个隐藏的div,div有固定的宽高,然后通过javascript动态去改变某些div的显示状态,table的高度会随着div的增加不断撑高,但把div隐藏之后table的高度不会随之减少,以至于页面会有一大遍空白的区域。此问题又不是必然出现且只有ie8以下浏览器的table标签会有这个问题。下面就把我的解决方案呈上。
//ie8以下浏览器子dom高度变化后,父容器高度没有回收,会有滚动条(可恶惨了)
){
var element = document.getElementById("childDiv"); //动态显示或隐藏的div节点
var pNode = element.parentNode;
while(pNode.tagName != "BODY"){
if(pNode.tagName == "TABLE") pNode.className = pNode.className; //浏览器会“重绘”Table,回收剩余空间;至于为什么,我没找到相关的解释
pNode = pNode.parentNode;
}
}
注:Sys.Browser 是一个通用对象,存放客户端浏览器的特性,请按需使用
其实就是遍历父table重新设定它的className,IE下诸如此类的问题还有很多,请按需使用。
五、iframe边框以及滚动的设定
var ciframe = document.createElement("iframe");
ciframe.setAttribute('frameborder', '0', 0); //隐藏边框 ie6、ie7
ciframe.setAttribute('scrolling', "no"); //隐藏滚动条
setAttribute第三个参数,object.setAttribute(sName, vValue [, iFlags])
sName参数应是Dom属性而非html中的属性。Dom中Html专有的接口属性应该以小写字母开头,如果属性有多个单词构成,第二个单词以及接下来的每个单词的首字母都要大写,如frameBorder。
另外说一下iflags参数:0:覆盖任何同名属性(忽略大小写) 1:默认,覆盖已经被设定的属性值 上面的问题我也可以setAttribute(‘frameborder’ , '0' , 0)实现。
六、阴影圆角功能
var divBox = document.getElementById("box"); //绝对定位的一个层
var divStyle = divBox.style;
if(Sys.Browser.isIE && Sys.Browser.version < 9){ //IE9以下的浏览器通过增加一个div来实现阴影
var shadowDiv = document.createElement("DIV");
shadowDiv.style.backgroundColor = "#ddd";
shadowDiv.style.zIndex = "999";
shadowDiv.style.position = "absolute";
document.body.appendChild(shadowDiv);
} else {
divStyle.boxShadow = "2px 2px 3px #ccc"; //css3支持阴影的属性(通用)
divStyle.borderRadius = "3px";
}
六、有点恶心的mousewheel和scrollTop兼容性
这是在开发过程中用javascript监听鼠标滚轮事件时遇到的问题,主要是针对不显示滚动条的容器进行的处理,为什么要隐藏滚动条呢?内容超出容器本身都会自动产生滚动条,当容器本身尺寸就比较小的情况下,显示纵横向两个滚动条就会占据多余位置,可以想象上图有滚动条是什么一个情景;另外系统滚动条不美观,而样式设置起来又会遇到兼容性,干脆自己实现滚动条功能吧。先贴代码,以下代码能完整运行。如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<style type="text/css">
html, body
{
background-color: #ffefbb;
padding: 0px;
margin: 0px;
height: 100%;
width: 100%;
overflow: hidden;
}
#content
{
font-family: "微软雅黑";
font-size: 12px;
color: #555;
text-align: left;
text-indent: 15px;
line-height: 20px;
padding: 5px;
margin: 0px;
}
</style>
</head>
<body>
<div id="content">
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明,不用过的的内容来渲染,简洁明了,如果显示不完就不现实滚动条,超出部分隐藏,帮助面板自动计算位置
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明,不用过的的内容来渲染,简洁明了,如果显示不完就不现实滚动条,超出部分隐藏,帮助面板自动计算位置
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明,不用过的的内容来渲染,简洁明了,如果显示不完就不现实滚动条,超出部分隐藏,帮助面板自动计算位置
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明,不用过的的内容来渲染,简洁明了,如果显示不完就不现实滚动条,超出部分隐藏,帮助面板自动计算位置
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明,不用过的的内容来渲染,简洁明了,如果显示不完就不现实滚动条,超出部分隐藏,帮助面板自动计算位置
帮助中心,帮助内容主要是一些文字性的描述,关于控件的功能介绍及说明
</div>
<script type="text/javascript">
var container = document.body;
var scrollTarget = document.getElementById("content");
function isChrome() {
var index = navigator.userAgent.search(/chrome/i);
return index > -1;
}
function bindEvent() {
var eventNames = ["DOMMouseScroll", "mousewheel"]; //Firefox->只支持addEventListener,DOMMouseScroll
if (container.attachEvent) {
container.onmousewheel = onMouseWheel; //IE
} else if (isChrome()) {
container.addEventListener(eventNames[1], onMouseWheel, false); //Chrome
} else {
container.addEventListener(eventNames[0], onMouseWheel, false); //Firefox
}
}
function onMouseWheel(e) {
var e = e || window.event;
var offset = 5;
if (e.type == "mousewheel") { //IE、Chrome
offset = e.wheelDelta / 12;
} else { //FireFox
offset = e.detail / 3 * -10;
};
container.scrollTop -= offset;
}
window.onload = function () {
bindEvent();
}
</script>
</body> </html>
上面的方法已完全解决了鼠标滚轮事件在各大主流浏览器的兼容性问题,但Chrome浏览器自身的一个bug,要实现滚轮代替滚动条的功能还得另外想办法。历经沧桑的感觉,突然想到用绝对定位的方法终于解决该问题了,贴代码,红色部分为新增代码:
<script type="text/javascript">
var container = document.body;
var scrollTarget = document.getElementById("content");
function isChrome() {
var index = navigator.userAgent.search(/chrome/i);
return index > -1;
}
function bindEvent() {
var eventNames = ["DOMMouseScroll", "mousewheel"]; //Firefox->只支持addEventListener,DOMMouseScroll
if (container.attachEvent) {
container.onmousewheel = onMouseWheel; //IE
} else if (isChrome()) {
container.addEventListener(eventNames[1], onMouseWheel, false); //Chrome
} else {
container.addEventListener(eventNames[0], onMouseWheel, false); //Firefox
}
}
function onMouseWheel(e) {
var e = e || window.event;
var offset = 5;
if (e.type == "mousewheel") { //IE、Chrome
offset = e.wheelDelta / 12;
} else { //FireFox
offset = e.detail / 3 * -10;
};
if (isChrome()) {
var domStyle = scrollTarget.style;
var top = parseInt(domStyle.top);
top += offset;
var minTop = (scrollTarget.offsetHeight * -1 + container.offsetHeight);
if (top > 0) top = 0;
else if (top < minTop) top = minTop;
domStyle.top = top + "px";
} else {
container.scrollTop -= offset;
}
}
function processChrome() {
if (!isChrome()) return;
var domStyle = scrollTarget.style;
domStyle.position = "absolute";
domStyle.top = "0px";
domStyle.left = "0px";
}
window.onload = function () {
processChrome();
bindEvent();
}
</script>
七、使用javascript对dom节点设置float浮动样式
dom节点的float样式在IE和firefox下对应的js脚本是不一样的,IE下对应得是styleFloat;firefox,chorme,safari下对应的是cssFloat,可用in运算符或者userAgent去检测style是否包含此属性。
var setFloat = function(obj,style) {
var sty = obj.style;
if('cssFloat' in sty){
obj.style.cssFloat = style;
} else if ('styleFloat' in sty){
obj.style.styleFloat = style;
} else {
throw 'set float style:' + style + 'error.';
}
}
八、浏览器关闭前事件的兼容性
//搜狗浏览器不支持该事件,可以放弃它
//支持:firefox,chrome,ie6-10,360极速及多标签模式
window.onbeforeunload = function (e) {
var e = e || window.event;
var msg = "离开本页将会立即退出本系统!";
if (e) e.returnValue = msg;
return msg;
};
九、对象模型的数组不支持indexOf,IE8浏览器
Array.indexOf = function Array$indexOf(array, item, start) {
if (typeof (item) === "undefined") return -1;
var length = array.length;
if (length !== 0) {
start = start - 0;
if (isNaN(start)) {
start = 0;
} else {
if (isFinite(start)) {
start = start - (start % 1);
}
if (start < 0) {
start = Math.max(0, length + start);
}
}
for (var i = start; i < length; i++) {
if ((typeof (array[i]) !== "undefined") && (array[i] === item)) {
return i;
}
}
}
return -1;
}
十、获取Iframe内部编辑框的值
function getIframeValue(frameId, domId){
var value;
var doc = document.getElementById(frameId).document;//ff chrome
if (!doc) doc = document.getElementById(frameId).contentWindow.document;//ie
var input = doc.getElementById(domId);
if(input) value = input.value;
return value;
}
本次总结
浏览器之间Javascript方面存在着不少的差异,要做到兼容,我觉得很有必要把一些常见的问题整理成一个javascript库。如DOM的操作、事件的处理、XMLHttpRequest请求等。目前比较流行的javascript库,不仅有丰富的UI,还有不同种类的控件与开发文档,如jQuery,ExtJs等。不过作为搞技术的人来说还是有必要了解一下这些差异性的本质原因,遇到问题才会迎刃而解。
浏览器兼容性之JavaScript篇的更多相关文章
- 浏览器兼容性汇总--JavaScript篇
目录 JavaScript中的兼容性汇总 1. HTML对象获取问题 2. const问题 3. event.x与event.y问题 4. wi ...
- 浏览器兼容性之Css篇
本文与上一篇随笔<浏览器兼容性之Javascript篇>有一定关联,下来我会继续不断总结,旨在解决浏览器兼容性,对遇到类似问题的同仁有所帮助,如有更多解决浏览器兼容性的案例还望大家分享一起 ...
- 浏览器兼容性汇总--CSS篇
目录 CSS篇 1. cursor:hand VS cursor:pointer 2. innerText在IE中能正常工作,但在FireFox中却不行 3. ...
- 浏览器兼容性小记-DOM篇(二)
1.DOM中的所有节点都继承自Node类型,IE9之前将DOM节点作为COM对象来实现:每个DOM节点都有一个nodeType属性来表明节点类型,总共有12个类型: Node.ELEMENT_NODE ...
- 浏览器兼容性小记-DOM篇(一)
1.childNodes引入空白节点问题:使用childElementCount或children 2.innerText: FF中不支持该属性,使用textContent代替 3.变量名与某HTML ...
- html浏览器兼容性的 JavaScript语法
1. 在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称.可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2. IE不支持JS ...
- 浏览器兼容性-JS篇
总结一下平时遇到的浏览器兼容性问题,本篇关于JS. 1.事件绑定 兼容写法: function add(obj,event){ if (obj.addEventListener) { obj.addE ...
- javascript中new Date浏览器兼容性处理
看下面的代码 <script type="text/javascript"> var dt1 = new Date('2016-3-4 11:06:12'); aler ...
- JAVASCRIPT 浏览器兼容性问题及解决方案列表
JAVASCRIPT 浏览器兼容性问题及解决方案列表(1)获取HTML元素只兼容IE:document.all.hello hello 兼容所有: document.getElementById(“h ...
随机推荐
- IE的layout属性详解
http://www.cnblogs.com/yuzhongwusan/archive/2012/03/09/2387052.html 很多在谷歌浏览器(chrome).火狐浏览器(Fire Fox) ...
- [SVN Mac自带SVN结合新浪SAE进行代码管理]
前一篇我转载了别人SVN的使用方法,前面的配置和服务器我不是很明白,自己尝试后发现我需要使用到的核心命令是下面一些. 新浪SAE提供了SVN代码管理仓库,只要进入相应应用,然后点击左侧代码管理,到最下 ...
- HD2059龟兔赛跑(DP)
题目链接 直接拿来当贪心做了=_=,然后就懵逼了 动态规划,本弱真没想到=_= #include <iostream> #include <cstdio> #include & ...
- Fix failed to start session in Ubuntu
When you are at login, press Ctrl+Alt+F1. It will take you to command line interface from the GUI. I ...
- 远程连接实验室的VPN
Windows 7 (win8类似)的用户请按以下步骤进行操作:1.点击“开始”菜单,然后点击“控制面板”,然后点击“查看网络和任务”.2.点击“设置新连接或网络”.3.点击“连接到工作区”,然后点击 ...
- List<T> 转换 DataTable
public class List2DataTable { public static string GetClassName(Type type) { if (typ ...
- vs------连接MySQL
转载: http://jingyan.baidu.com/article/8ebacdf023953f49f65cd589.html
- LDA(转发)
主题模型-LDA浅析 分类: 数据挖掘 机器学习2012-09-03 14:09 24937人阅读 评论(16) 收藏 举报 文档allocationsemanticeach算法网络 上个月参加了在北 ...
- 使用ThreadLocal、Apache的dbutils的QueryRunner和dbcp2数据库连接池的BasicDataSource封装操作数据库工具
package hjp.smart4j.framework.helper; import hjp.smart4j.framework.util.CollectionUtil; import hjp.s ...
- ecshop自动退出
在使用ecshop后台的时候,老是自动退出,影响正常使用. 解决办法: 在includes/cls_session.php中,function gen_session_key($session_id) ...