近期公司职务变动,我大部分工作时间都在做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篇的更多相关文章

  1. 浏览器兼容性汇总--JavaScript篇

    目录 JavaScript中的兼容性汇总 1.        HTML对象获取问题 2.        const问题 3.        event.x与event.y问题 4.        wi ...

  2. 浏览器兼容性之Css篇

    本文与上一篇随笔<浏览器兼容性之Javascript篇>有一定关联,下来我会继续不断总结,旨在解决浏览器兼容性,对遇到类似问题的同仁有所帮助,如有更多解决浏览器兼容性的案例还望大家分享一起 ...

  3. 浏览器兼容性汇总--CSS篇

    目录 CSS篇 1.       cursor:hand   VS   cursor:pointer 2.        innerText在IE中能正常工作,但在FireFox中却不行 3.     ...

  4. 浏览器兼容性小记-DOM篇(二)

    1.DOM中的所有节点都继承自Node类型,IE9之前将DOM节点作为COM对象来实现:每个DOM节点都有一个nodeType属性来表明节点类型,总共有12个类型: Node.ELEMENT_NODE ...

  5. 浏览器兼容性小记-DOM篇(一)

    1.childNodes引入空白节点问题:使用childElementCount或children 2.innerText: FF中不支持该属性,使用textContent代替 3.变量名与某HTML ...

  6. html浏览器兼容性的 JavaScript语法

    1.      在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称.可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2.      IE不支持JS ...

  7. 浏览器兼容性-JS篇

    总结一下平时遇到的浏览器兼容性问题,本篇关于JS. 1.事件绑定 兼容写法: function add(obj,event){ if (obj.addEventListener) { obj.addE ...

  8. javascript中new Date浏览器兼容性处理

    看下面的代码 <script type="text/javascript"> var dt1 = new Date('2016-3-4 11:06:12'); aler ...

  9. JAVASCRIPT 浏览器兼容性问题及解决方案列表

    JAVASCRIPT 浏览器兼容性问题及解决方案列表(1)获取HTML元素只兼容IE:document.all.hello hello 兼容所有: document.getElementById(“h ...

随机推荐

  1. Swift 吐槽下Swift里一个逼死强迫症的语法:中缀语法

    中缀语法是OC里特有的一种,就是在函数的参数前面加一个解释词,让调用的时候明白该参数的含义 比如: -(void)processDataWithparamaA:(NSString *)paramaA ...

  2. Unity连Photon服务器入门详解

    Photon是目前比较好用的游戏服务器.目前网上对于Photon的服务器讲解比较少,最近也对Photon做了初步的了解,做一个极其详细的入门. 首先就是得下载Photon咯 https://www.p ...

  3. 第一章,Linux常用命令

    20161124 Linux常用命令1.find find /etc/ -size +50k -lsfind /etc/ -size +50k -ls 2> /dev/null查看目录下大于50 ...

  4. 常用机器视觉工具----图像分析工具(blob分析)

    http://blog.sina.com.cn/s/blog_67cc4eb70100ivnt.html Blob分析:Blob分析目的在于对图像中的2-D形状进行检测和分析,得到诸如目标位置.形状. ...

  5. BZOJ3159: 决战

    方法很简单,树剖,把区间提取出来,打翻转标记,再放回去. 注意:由于某种原因,我写的是把题目中的r忽略掉的一般情况,否则简单得多. 本来以为写起来也很简单T_T #include<bits/st ...

  6. redis哨兵配置

    redis哨兵配置主从   redis哨兵的启动和redis实例的启动没有关系.所以可以在任何机器上启动redis哨兵.至少要保证有两个哨兵在运行,要不然宕机后哨兵会找不到主节点. 配置步骤: 1.在 ...

  7. JSP简单标签开发

    一.继承自SimpleTag接口的自定义标签实现类称为简单标签,接口中5个方法 1.setJspContext方法 用于把JSP页面的PageContext对象传递给标签处理器对象 2.setPare ...

  8. JavaWeb学习笔记——开发动态WEB资源(八)cookies和httpsession

    会话: cookies: (1)cookies是WEB服务器发送到浏览器的简短文本信息 (2)cookies可以禁用 httpsession: 一次会话是从你打开浏览器开始到你关闭浏览器结束 提供一种 ...

  9. 最好用的placeholder插件,jQuery插件EnPlaceholder

    EnPlaceholder插件支持密码框哦!实际对比同类的placeholder插件在ie等浏览器下效果做好! 插件效果预览:http://www.wufangbo.com/demo/jquery/3 ...

  10. js中event的target和currentTarget的区别

    js中的event对象包含很多有用的信息 target:触发事件的元素. currentTarget:事件绑定的元素. 两者在没有冒泡的情况下,是一样的值,但在用了事件委托的情况下,就不一样了,例如: ...