登录  /  注册
首页 > web前端 > js教程 > 正文

JavaScript关于IE8兼容问题的处理

php中世界最好的语言
发布: 2018-03-16 14:28:04
原创
7606人浏览过

这次给大家带来JavaScript关于IE8兼容问题的处理,JavaScript关于IE8兼容问题处理的注意事项有哪些,下面就是实战案例,一起来看一下。

最初对做兼容性的认知只停留在UI层面,但其实UI层面都还好,因为毕竟你可以直接看得见现象,更为重要的是在JavaScript层面,因为这个部分涉及到功能性,前者最多是体验性的问题。下面扯一下这几天遇到的IE8相关的兼容性问题。

1.所有$.ajax失效

刚开始看到的现象是IE8/9页面切到了留言页面,没有进入正常流程。打开fiddler都没抓到请求,奇怪了,打出$.ajax error方法中的返回值。xhr.status的值都是0,原来请求没有发出去。心想:怎么没有发出去呢,难道是跨域问题,不对啊,服务端已经允许跨域了。后来一查(IE8/9下的跨域资源请求),原来请求被IE8/9阻止了,所以服务端允许跨域了也没有用。当时网上有两种办法,1个是设置浏览器,允许通过域访问数据源。2个是加入一个js插件,也就是让IE8/9/10走IE自己支持的XDomainRequest发送请求。第一个方法只能玩玩,不可能让用户去操作套路那么深的步骤。第二个方法github上有两套js。

https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest

https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

引用后都不用改代码,刚开始还有点小激动。

<!--[if (IE 8)|(IE 9)]><script src="Js/jQuery.XDOmainRequest.js"></script><![endif]-->
登录后复制

加上去一看,请求发过去了,界面进入了正常流程。but,又发现返回的值不对,说与服务端,服务端说你的值没传过来,怎么可能,代码都没动,原来这个XDomainRequest是参数走的header,先天性缺少contentType,没有参数的请求返回是正确的,有参数的后台就没有读到。又寻思着难道要后台改代码,支持一下这种方式?我迟疑了。然后就到群里和队友们讨论下。大家给出的方案就是,用Nginx配置个代理就好了。啊,一时激动的有点难以言表。绕了一大圈,啥都不用改,服务器上配置下就好了。因为,既然是跨域问题,最根本的方法就是让它不用跨域了。这种前后端分离的架构,网站(html)和api都是不同的域名.

location /api/-Real--Forwarded-//./api/;
 }
登录后复制

所以这才是最佳解决方案。当时就想,自己对跨域的认知不足,遇到问题都是横向的找办法,没有往上层想。还是有给力的队友。这个问题stackoverflow也有讨论:

http://stackoverflow.com/questions/10232017/ie9-jquery-ajax-with-cors-returns-access-is-denied

http://stackoverflow.com/questions/3362474/jquery-ajax-fails-in-ie-on-cross-domain-calls

2.消息怎么变长了

这个问题的现象看起来很神奇,用户在IE8上发送长消息(比如1000字)开始能显示在对话框中,但是一刷新就没了。别的浏览器刷新后长消息都还在。我打开日志,ajax是进入了成功回调,但是返回值有文字提示:'消息过长被阻止'。也就是说我看成功回调了就立马显示到界面上了,但是并没有成功,所以刷新之后拿不到那条消息。ajax的succes只是代表请求成功,并不代表调用api对了。这是我犯得低级错误,没有和api同事确认。但为什么消息会变长呢,一开始把字数调500,ie8能够发了。说明请求确实变长了。打开日志发现。汉字都被转码了。比如:

    var data={name:"博客园"}
     alert(JSON.stringify(data));
登录后复制

IE8会得到

也就是说本质上是json转义的问题。之前给ie8加了一个json2.

<!--[if IE 8]><script src="json2.min.js"></script><![endif]-->
登录后复制

看来还不行。换成json3,1000字也正常了。

<!--[if IE 8]><script src="json3.min.js"></script><![endif]-->
登录后复制

3.flash检测

如果你想准确的判断用户的IE到底有没flash。得用SWFObject对象

/*!    SWFObject v2.3.20130521 <http:>
    is released under the MIT License <http:>*/var swfobject = function () {    var D = "undefined", r = "object", T = "Shockwave Flash", Z = "ShockwaveFlash.ShockwaveFlash", q = "application/x-shockwave-flash", S = "SWFObjectExprInst", x = "onreadystatechange", Q = window, h = document, t = navigator, V = false, X = [], o = [], P = [], K = [], I, p, E, B, L = false, a = false, m, G, j = true, l = false, O = function () { var ad = typeof h.getElementById != D &amp;&amp; typeof h.getElementsByTagName != D &amp;&amp; typeof h.createElement != D, ak = t.userAgent.toLowerCase(), ab = t.platform.toLowerCase(), ah = ab ? /win/.test(ab) : /win/.test(ak), af = ab ? /mac/.test(ab) : /mac/.test(ak), ai = /webkit/.test(ak) ? parseFloat(ak.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, aa = t.appName === "Microsoft Internet Explorer", aj = [0, 0, 0], ae = null; if (typeof t.plugins != D &amp;&amp; typeof t.plugins[T] == r) { ae = t.plugins[T].description; if (ae &amp;&amp; (typeof t.mimeTypes != D &amp;&amp; t.mimeTypes[q] &amp;&amp; t.mimeTypes[q].enabledPlugin)) { V = true; aa = false; ae = ae.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); aj[0] = n(ae.replace(/^(.*)\..*$/, "$1")); aj[1] = n(ae.replace(/^.*\.(.*)\s.*$/, "$1")); aj[2] = /[a-zA-Z]/.test(ae) ? n(ae.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0 } } else { if (typeof Q.ActiveXObject != D) { try { var ag = new ActiveXObject(Z); if (ag) { ae = ag.GetVariable("$version"); if (ae) { aa = true; ae = ae.split(" ")[1].split(","); aj = [n(ae[0]), n(ae[1]), n(ae[2])] } } } catch (ac) { } } } return { w3: ad, pv: aj, wk: ai, ie: aa, win: ah, mac: af } }(), i = function () { if (!O.w3) { return } if ((typeof h.readyState != D &amp;&amp; (h.readyState === "complete" || h.readyState === "interactive")) || (typeof h.readyState == D &amp;&amp; (h.getElementsByTagName("body")[0] || h.body))) { f() } if (!L) { if (typeof h.addEventListener != D) { h.addEventListener("DOMContentLoaded", f, false) } if (O.ie) { h.attachEvent(x, function aa() { if (h.readyState == "complete") { h.detachEvent(x, aa); f() } }); if (Q == top) { (function ac() { if (L) { return } try { h.documentElement.doScroll("left") } catch (ad) { setTimeout(ac, 0); return } f() }()) } } if (O.wk) { (function ab() { if (L) { return } if (!/loaded|complete/.test(h.readyState)) { setTimeout(ab, 0); return } f() }()) } } }(); function f() { if (L || !document.getElementsByTagName("body")[0]) { return } try { var ac, ad = C("span"); ad.style.display = "none"; ac = h.getElementsByTagName("body")[0].appendChild(ad); ac.parentNode.removeChild(ac); ac = null; ad = null } catch (ae) { return } L = true; var aa = X.length; for (var ab = 0; ab  0) { for (var ai = 0; ai  0) { var ah = c(ab); if (ah) { if (F(o[ai].swfVersion) &amp;&amp; !(O.wk &amp;&amp; O.wk <param>" + ab + ""; return ac.firstChild } function u(ai, ag, ab) { var aa, ad = c(ab); ab = W(ab); if (O.wk &amp;&amp; O.wk  aa[0] || (ab[0] == aa[0] &amp;&amp; ab[1] &gt; aa[1]) || (ab[0] == aa[0] &amp;&amp; ab[1] == aa[1] &amp;&amp; ab[2] &gt;= aa[2])) ? true : false } function v(af, ab, ag, ae) { var ad = h.getElementsByTagName("head")[0]; if (!ad) { return } var aa = (typeof ag == "string") ? ag : "screen"; if (ae) { m = null; G = null } if (!m || G != aa) { var ac = C("style"); ac.setAttribute("type", "text/css"); ac.setAttribute("media", aa); m = ad.appendChild(ac); if (O.ie &amp;&amp; typeof h.styleSheets != D &amp;&amp; h.styleSheets.length &gt; 0) { m = h.styleSheets[h.styleSheets.length - 1] } G = aa } if (m) { if (typeof m.addRule != D) { m.addRule(af, ab) } else { if (typeof h.createTextNode != D) { m.appendChild(h.createTextNode(af + " {" + ab + "}")) } } } } function w(ad, aa) { if (!j) { return } var ab = aa ? "visible" : "hidden", ac = c(ad); if (L &amp;&amp; ac) { ac.style.visibility = ab } else { if (typeof ad === "string") { v("#" + ad, "visibility:" + ab) } } } function N(ab) { var ac = /[\\\"\.;]/; var aa = ac.exec(ab) != null; return aa &amp;&amp; typeof encodeURIComponent != D ? encodeURIComponent(ab) : ab } var d = function () { if (O.ie) { window.attachEvent("onunload", function () { var af = K.length; for (var ae = 0; ae <p style="text-align: left;">View Code</p>
<pre class="brush:php;toolbar:false"> function hasFlash() {        return swfobject.hasFlashPlayerVersion("1");
    }
登录后复制

通过这方法判断是最准确的。

4.图片显示问题

1)在https的网站上出现http的请求,浏览器都会给出安全提醒,就ie喜欢弹出来。

这个也还好,微信在ie8中打开也会有这样的提示,除非文件服务器也是https的,不然前端也是没解。如果是在https中请求http的ajax,那直接挂掉。

2)IE8上在界面对大图片设置max-width,会出现把父元素撑得很大而图片显示在一边,留下一大块空白。这个解决办法就是给父类也加个max-width的样式限制一下。

5.socket.io遇到https

这是这几天一个严重的问题,到https上,ie8/9都收不到消息。我为之很苦恼,因为socket都显示连接成功了,也订阅消息了,就是没收到消息。这个socket.io号称都支持到ie6的。各种搜索都没有看到过相关问题。我有个经验,如果一个问题,你搜了很都没有找到类似的问题,可能有两点,要么这是个很傻的问题,哪个地方设置下就好了,要么就是个很偏很冷门的问题。但是明显前者的可能性更大。

  socket = io('/', { 'transports': ['websocket', 'polling'] });
  socket.on("connect", function () {  console.log('连接成功')                                    
  }); //监听频道
 socket.on('messages', function (res) {
 console.log("收到消息",res);
 });
登录后复制

其实在http上的测试环境ie8是ok的,有一天晚上突然调通了,我还高兴的备份了代码回家睡了个好觉,第二天一来打开一看,懵逼了,还是不行。难道是幻觉,昨天还在群里和队友说好了,真是啪啪啪的打脸。然后再也没通过了。其实socket.io的调用代码很简单,就那么几句。我再怎么摆弄也没啥用。最后还是没办法,在ie8/9上面切到了传统的轮询。这个问题最后还是没有解决,同事说可能是F5或者https的安全协议引起的。

6.不支持数组的indexof

如果是现代浏览器我们可以通过indexOf来判断一个元素是否存在于数组

if (!~loadmesg.indexOf(json.MsgID))
登录后复制

但ie8不支持。得改成for循环。

7.隐藏元素初始化上传插件失败

上传的时候使用的是plupload插件,但如果目标元素是隐藏的,ie8上初始化会无效。

8.IE标准模式失效

我们可以用mate来指定ie8的渲染方式:

  <meta>
登录后复制

但我发现无论我怎么加,都是以ie7的方式打开的。然后就重新做了简单的也没,只有meta和文字,发现是有效果的,也就是说页面上的某些原因导致ie8又自己切换到了ie7的兼容模式

然后拿掉就可以了。之前这么写是为了添加一个过渡的样式。没想到造成了这种影响。只有再换一种方式实现。

9.jquery的一种写法不支持

 var $a = $('<a></a>');            var img = '<img  alt="JavaScript关于IE8兼容问题的处理" >';
            $a.html(img);
            $(".hold").append($a);
登录后复制

引用的是jquery1.11.3 在ie8中会报错。修改如下:

 var str = '<a><img  alt="JavaScript关于IE8兼容问题的处理" ></a>'
            $(".hold").append(str);
登录后复制

小结:做兼容性也是为了体验性和稳定性,每一个异常现象背后都是对一些基础知识的考验,以前做网站基本上都是一个人从头做到位,跨域问题几乎都没遇到过,兼容性上也没有死磕。现在正经做前端几个月了,感觉做兼容性是每个前端的必备课,后端都知道现代浏览器方便好用,但是你写代码是为了服务用户的,不是方便自己,再者,做兼容性确实考验各方面的知识,最好前端还是要懂后端的以及网络方面的知识。这样遇到问题的时候不至于茫然无措,因为前端看到的现象已经是异常的最后面目,你要分析找出最根本的原因,然后找对应的同事帮忙解决

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

微信分享功能的开发

公众号支付接口的开发

H5的缓存Manifest的使用

以上就是JavaScript关于IE8兼容问题的处理的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号