浏览器兼容性之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 ...
随机推荐
- [iOS 利用MapKit和CoreLocation框架打造精简的定位和导航]
运行效果: 一.利用<CoreLocation/CoreLocation.h>定位 创建变量 CLLocationManager *locationManager , ...
- <base href="<%=basePath%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 【Beta】第三次任务发布
后端(补做) #86 了解社区新建文章.添加评论(回复)的机制.整理成API文档,包括如何请求新建文章.新建评论(回复).如何获取文章内容和评论内容. 验收条件:文档PM要能看懂. 前端(补做) #8 ...
- js中substring与substr的学习。
今天在工作的过程中,看到js中两个双胞胎函数.分别是substring与substr.顿时被两个可恶的家伙给迷惑住了,不知道具体有什么作用.. 先来看看substring手册是怎么介绍的. 手册解释的 ...
- linux Basis --- tar command
-c: compress archives -x:decompress archives -t:check archives -z:whether it has the attribute of gz ...
- netty socket 客服端编程
package com.ming.netty.nio; 2 3 import io.netty.bootstrap.Bootstrap; 4 import io.netty.channel.Chann ...
- C#获取C++中修改过的float数组(指针),dll
C++中 struct rankPoint{ float sim; }; ]){ ; i < ; i++) prank[i].sim = ; ; i < ; i++) prank[i].s ...
- CS架构和BS架构的区别
C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势. ...
- MyISAM 和InnoDB 区别 转
MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处理 ...
- Java数据结构——容器总结
4大容器——List.Set.Queue.Map List 1.ArrayList 优点:随机访问元素 缺点:插入和移除元素时较慢 2.LinkedList 优点:插入和删除元素 缺点:随机访问方面相 ...