近期公司职务变动,我大部分工作时间都在做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. Markdown编辑器简单总结

    字体大小: #1 ##2 添加链接: 文字链接 [blog](http://yalantis.com/blog/how_we_created_tab_bar_animation_for_ios/?ut ...

  2. Spring mvc web 配置

    Spring Framework本身没有Web功能, Spring MVC使用WebApplicationContext类扩展ApplicationContext ,使得拥有web功能.那么,Spri ...

  3. C#位操作与枚举的应用

    看到代码里有用位操作来判断条件的,以前没有这么用过,做个笔记: int add = 2; int modify = 4; int delete = 8; Console.WriteLine((add ...

  4. CentOS 下安装

    2016年12月5日15:25:58 ----------------------------------- 通常情况下在centos下安装软件就用yum. 关键是,使用yum你要知道安装包的名字是什 ...

  5. linux配置网卡

    我爱折腾.在本地虚拟机里装了linux的环境.要配置linux的网卡文件. 如下: vi /etc/sysconfig/network-script/ifcfg-eth0; 刚装完系统,没有vim , ...

  6. Altium Designer 15 --- PCB 3D View

    press 3 key to swith to 3D view, and press shift key and dont' loose your grip, hold the right mouse ...

  7. git命令拾遗

    要随时掌握工作区的状态,使用git status命令. 如果git status告诉你有文件被修改过,用git diff可以查看修改内容. HEAD指向的版本就是当前版本,因此,Git允许我们在版本的 ...

  8. C++ 纯虚函数接口,标准 C 导出 DLL 函数的用法

    CMakeLists.txt project(virtual) # 创建工程 virtual add_library(virtual SHARED virtual.cpp) # 创建动态连接库 lib ...

  9. MVC实现动态二级域名

    前段时间,一个朋友问我ASP.NET MVC下实现动态二级域名的问题.跟他聊了一些解决方案,这里也总结一下,以供参考. 相信大家都发现类似58同城这样的网站,成都的网址是cd.58.com 上海的是s ...

  10. 第一次使用Android Studio时你应该知道的一切配置

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...