浏览器兼容性之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 ...
随机推荐
- QIBO CMS SQL Injection Via Variable Uninitialization In \member\special.php
Catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 该漏洞存在于/member/special.php文件下,由于未对变量进 ...
- Unity3d5.0 新UI之2048
因为汽车系统没写出来所以,纠结之中,弄了弄新版本的UI. 做了个2048. 新版本的unity的UI必须以Canvas为基底来呈现,如果没有加画布的话可是显示不出来东西的哦. 而且作为UI上的所有组件 ...
- git本地分支
1. 新建并切换到该分支 $ git checkout -b iss53 Switched to a new branch 'iss53' 相当于: $ git branch iss53$ git c ...
- Beta版本——第六次冲刺博客
我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...
- Linux 吃掉我的内存
在Windows下资源管理器查看内存使用的情况,如果使用率达到80%以上,再运行大程序就能感觉到系统不流畅了,因为在内存紧缺的情况下使用交换分区,频繁地从磁盘上换入换出页会极大地影响系统的性能.而当我 ...
- Python基本数据类型之list
一.创建列表: li = [] li = list() name_list = ['alex', 'seven', 'eric'] name_list = list(['alex', 'seven', ...
- 今天执行grep命令差点把服务器搞崩
grep "rst" -r ./ >> a.log 今天执行这个命令差点把服务器搞崩了. 本意是查找所有源代码文件中含有rst字符串的行,打印到文件a.log中,然后进 ...
- hibernate实现有两种配置,xml配置与注释配置。
(1):xml配置:hibernate.cfg.xml (放到src目录下)和实体配置类:xxx.hbm.xml(与实体为同一目录中) <?xml version='1.0' encoding= ...
- (转)JS Date格式化为yyyy-MM-dd类字符串
Date.prototype.format = function(format){ var o = { "M+" : this.getMonth()+1, //month &quo ...
- json_encode详解,转义
1.json_encod基本用法:数组转字符串 <?php $arr = array (,,,,); echo json_encode($arr); ?> 以上例程会输出: {,,,,} ...