Home  >  Article  >  Web Front-end  >  JavaScript's handling of IE8 compatibility issues

JavaScript's handling of IE8 compatibility issues

php中世界最好的语言
php中世界最好的语言Original
2018-03-16 14:28:047850browse

这次给大家带来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://github.com/swfobject/swfobject>
    is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>*/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 && typeof h.getElementsByTagName != D && 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 && typeof t.plugins[T] == r) { ae = t.plugins[T].description; if (ae && (typeof t.mimeTypes != D && t.mimeTypes[q] && 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 && (h.readyState === "complete" || h.readyState === "interactive")) || (typeof h.readyState == D && (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 < aa; ab++) { X[ab]() } } function M(aa) { if (L) { aa() } else { X[X.length] = aa } } function s(ab) { if (typeof Q.addEventListener != D) { Q.addEventListener("load", ab, false) } else { if (typeof h.addEventListener != D) { h.addEventListener("load", ab, false) } else { if (typeof Q.attachEvent != D) { g(Q, "onload", ab) } else { if (typeof Q.onload == "function") { var aa = Q.onload; Q.onload = function () { aa(); ab() } } else { Q.onload = ab } } } } } function Y() { var aa = h.getElementsByTagName("body")[0]; var ae = C(r); ae.setAttribute("style", "visibility: hidden;"); ae.setAttribute("type", q); var ad = aa.appendChild(ae); if (ad) { var ac = 0; (function ab() { if (typeof ad.GetVariable != D) { try { var ag = ad.GetVariable("$version"); if (ag) { ag = ag.split(" ")[1].split(","); O.pv = [n(ag[0]), n(ag[1]), n(ag[2])] } } catch (af) { O.pv = [8, 0, 0] } } else { if (ac < 10) { ac++; setTimeout(ab, 10); return } } aa.removeChild(ae); ad = null; H() }()) } else { H() } } function H() { var aj = o.length; if (aj > 0) { for (var ai = 0; ai < aj; ai++) { var ab = o[ai].id; var ae = o[ai].callbackFn; var ad = { success: false, id: ab }; if (O.pv[0] > 0) { var ah = c(ab); if (ah) { if (F(o[ai].swfVersion) && !(O.wk && O.wk < 312)) { w(ab, true); if (ae) { ad.success = true; ad.ref = z(ab); ad.id = ab; ae(ad) } } else { if (o[ai].expressInstall && A()) { var al = {}; al.data = o[ai].expressInstall; al.width = ah.getAttribute("width") || "0"; al.height = ah.getAttribute("height") || "0"; if (ah.getAttribute("class")) { al.styleclass = ah.getAttribute("class") } if (ah.getAttribute("align")) { al.align = ah.getAttribute("align") } var ak = {}; var aa = ah.getElementsByTagName("param"); var af = aa.length; for (var ag = 0; ag < af; ag++) { if (aa[ag].getAttribute("name").toLowerCase() != "movie") { ak[aa[ag].getAttribute("name")] = aa[ag].getAttribute("value") } } R(al, ak, ab, ae) } else { b(ah); if (ae) { ae(ad) } } } } } else { w(ab, true); if (ae) { var ac = z(ab); if (ac && typeof ac.SetVariable != D) { ad.success = true; ad.ref = ac; ad.id = ac.id } ae(ad) } } } } } X[0] = function () { if (V) { Y() } else { H() } }; function z(ac) { var aa = null, ab = c(ac); if (ab && ab.nodeName.toUpperCase() === "OBJECT") { if (typeof ab.SetVariable !== D) { aa = ab } else { aa = ab.getElementsByTagName(r)[0] || ab } } return aa } function A() { return !a && F("6.0.65") && (O.win || O.mac) && !(O.wk && O.wk < 312) } function R(ad, ae, aa, ac) {        var ah = c(aa); aa = W(aa); a = true; E = ac || null; B = { success: false, id: aa }; if (ah) {            if (ah.nodeName.toUpperCase() == "OBJECT") { I = J(ah); p = null } else { I = ah; p = aa } ad.id = S; if (typeof ad.width == D || (!/%$/.test(ad.width) && n(ad.width) < 310)) { ad.width = "310" } if (typeof ad.height == D || (!/%$/.test(ad.height) && n(ad.height) < 137)) { ad.height = "137" } var ag = O.ie ? "ActiveX" : "PlugIn", af = "MMredirectURL=" + encodeURIComponent(Q.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + ag + "&MMdoctitle=" + encodeURIComponent(h.title.slice(0, 47) + " - Flash Player Installation"); if (typeof ae.flashvars != D) { ae.flashvars += "&" + af } else { ae.flashvars = af } if (O.ie && ah.readyState != 4) {                var ab = C("p");
                aa += "SWFObjectNew"; ab.setAttribute("id", aa); ah.parentNode.insertBefore(ab, ah); ah.style.display = "none"; y(ah)
            } u(ad, ae, aa)
        }
    } function b(ab) { if (O.ie && ab.readyState != 4) { ab.style.display = "none"; var aa = C("p"); ab.parentNode.insertBefore(aa, ab); aa.parentNode.replaceChild(J(ab), aa); y(ab) } else { ab.parentNode.replaceChild(J(ab), ab) } } function J(af) { var ae = C("p"); if (O.win && O.ie) { ae.innerHTML = af.innerHTML } else { var ab = af.getElementsByTagName(r)[0]; if (ab) { var ag = ab.childNodes; if (ag) { var aa = ag.length; for (var ad = 0; ad < aa; ad++) { if (!(ag[ad].nodeType == 1 && ag[ad].nodeName == "PARAM") && !(ag[ad].nodeType == 8)) { ae.appendChild(ag[ad].cloneNode(true)) } } } } } return ae } function k(aa, ab) { var ac = C("p"); ac.innerHTML = "<object classid=&#39;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&#39;><param name=&#39;movie&#39; value=&#39;" + aa + "&#39;>" + ab + "</object>"; return ac.firstChild } function u(ai, ag, ab) { var aa, ad = c(ab); ab = W(ab); if (O.wk && O.wk < 312) { return aa } if (ad) { var ac = (O.ie) ? C("p") : C(r), af, ah, ae; if (typeof ai.id == D) { ai.id = ab } for (ae in ag) { if (ag.hasOwnProperty(ae) && ae.toLowerCase() !== "movie") { e(ac, ae, ag[ae]) } } if (O.ie) { ac = k(ai.data, ac.innerHTML) } for (af in ai) { if (ai.hasOwnProperty(af)) { ah = af.toLowerCase(); if (ah === "styleclass") { ac.setAttribute("class", ai[af]) } else { if (ah !== "classid" && ah !== "data") { ac.setAttribute(af, ai[af]) } } } } if (O.ie) { P[P.length] = ai.id } else { ac.setAttribute("type", q); ac.setAttribute("data", ai.data) } ad.parentNode.replaceChild(ac, ad); aa = ac } return aa } function e(ac, aa, ab) { var ad = C("param"); ad.setAttribute("name", aa); ad.setAttribute("value", ab); ac.appendChild(ad) } function y(ac) { var ab = c(ac); if (ab && ab.nodeName.toUpperCase() == "OBJECT") { if (O.ie) { ab.style.display = "none"; (function aa() { if (ab.readyState == 4) { for (var ad in ab) { if (typeof ab[ad] == "function") { ab[ad] = null } } ab.parentNode.removeChild(ab) } else { setTimeout(aa, 10) } }()) } else { ab.parentNode.removeChild(ab) } } } function U(aa) { return (aa && aa.nodeType && aa.nodeType === 1) } function W(aa) { return (U(aa)) ? aa.id : aa } function c(ac) { if (U(ac)) { return ac } var aa = null; try { aa = h.getElementById(ac) } catch (ab) { } return aa } function C(aa) { return h.createElement(aa) } function n(aa) { return parseInt(aa, 10) } function g(ac, aa, ab) { ac.attachEvent(aa, ab); K[K.length] = [ac, aa, ab] } function F(ac) { ac += ""; var ab = O.pv, aa = ac.split("."); aa[0] = n(aa[0]); aa[1] = n(aa[1]) || 0; aa[2] = n(aa[2]) || 0; return (ab[0] > aa[0] || (ab[0] == aa[0] && ab[1] > aa[1]) || (ab[0] == aa[0] && ab[1] == aa[1] && ab[2] >= 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 && typeof h.styleSheets != D && h.styleSheets.length > 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 && 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 && 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 < af; ae++) { K[ae][0].detachEvent(K[ae][1], K[ae][2]) } var ac = P.length; for (var ad = 0; ad < ac; ad++) { y(P[ad]) } for (var ab in O) { O[ab] = null } O = null; for (var aa in swfobject) { swfobject[aa] = null } swfobject = null }) } }(); return {
        registerObject: function (ae, aa, ad, ac) { if (O.w3 && ae && aa) { var ab = {}; ab.id = ae; ab.swfVersion = aa; ab.expressInstall = ad; ab.callbackFn = ac; o[o.length] = ab; w(ae, false) } else { if (ac) { ac({ success: false, id: ae }) } } }, getObjectById: function (aa) { if (O.w3) { return z(aa) } }, embedSWF: function (af, al, ai, ak, ab, ae, ad, ah, aj, ag) { var ac = W(al), aa = { success: false, id: ac }; if (O.w3 && !(O.wk && O.wk < 312) && af && al && ai && ak && ab) { w(ac, false); M(function () { ai += ""; ak += ""; var an = {}; if (aj && typeof aj === r) { for (var aq in aj) { an[aq] = aj[aq] } } an.data = af; an.width = ai; an.height = ak; var ar = {}; if (ah && typeof ah === r) { for (var ao in ah) { ar[ao] = ah[ao] } } if (ad && typeof ad === r) { for (var am in ad) { if (ad.hasOwnProperty(am)) { var ap = (l) ? encodeURIComponent(am) : am, at = (l) ? encodeURIComponent(ad[am]) : ad[am]; if (typeof ar.flashvars != D) { ar.flashvars += "&" + ap + "=" + at } else { ar.flashvars = ap + "=" + at } } } } if (F(ab)) { var au = u(an, ar, al); if (an.id == ac) { w(ac, true) } aa.success = true; aa.ref = au; aa.id = au.id } else { if (ae && A()) { an.data = ae; R(an, ar, al, ag); return } else { w(ac, true) } } if (ag) { ag(aa) } }) } else { if (ag) { ag(aa) } } }, switchOffAutoHideShow: function () { j = false }, enableUriEncoding: function (aa) { l = (typeof aa === D) ? true : aa }, ua: O, getFlashPlayerVersion: function () { return { major: O.pv[0], minor: O.pv[1], release: O.pv[2] } }, hasFlashPlayerVersion: F, createSWF: function (ac, ab, aa) { if (O.w3) { return u(ac, ab, aa) } else { return undefined } }, showExpressInstall: function (ac, ad, aa, ab) { if (O.w3 && A()) { R(ac, ad, aa, ab) } }, removeSWF: function (aa) { if (O.w3) { y(aa) } }, createCSS: function (ad, ac, ab, aa) { if (O.w3) { v(ad, ac, ab, aa) } }, addDomLoadEvent: M, addLoadEvent: s, getQueryParamValue: function (ad) {            var ac = h.location.search || h.location.hash;            if (ac) { if (/\?/.test(ac)) { ac = ac.split("?")[1] } if (ad == null) { return N(ac) } var ab = ac.split("&"); for (var aa = 0; aa < ab.length; aa++) { if (ab[aa].substring(0, ab[aa].indexOf("=")) == ad) { return N(ab[aa].substring((ab[aa].indexOf("=") + 1))) } } } return ""
        }, expressInstallCallback: function () { if (a) { var aa = c(S); if (aa && I) { aa.parentNode.replaceChild(I, aa); if (p) { w(p, true); if (O.ie) { I.style.display = "block" } } if (E) { E(B) } } a = false } }, version: "2.3"
    }
}();

View Code

 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(&#39;/&#39;, { &#39;transports&#39;: [&#39;websocket&#39;, &#39;polling&#39;] });
  socket.on("connect", function () {  console.log(&#39;连接成功&#39;)                                    
  }); //监听频道
 socket.on(&#39;messages&#39;, 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 http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

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

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

9.jquery的一种写法不支持

 var $a = $('<a target="_blank" class="&#39; + c + &#39;"     href=&#39; + rightData[i].CustomerRightNavLink + &#39;></a>');            var img = '<img src=&#39; + rightData[i].CustomerRightNavImage + &#39; />';
            $a.html(img);
            $(".hold").append($a);

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

 var str = '<a target="_blank" class="&#39; + c + &#39;"     href=&#39; + rightData[i].CustomerRightNavLink + &#39;><img src=&#39; + rightData[i].CustomerRightNavImage + &#39; /></a>'
            $(".hold").append(str);

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

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

推荐阅读:

微信分享功能的开发

公众号支付接口的开发

H5的缓存Manifest的使用

The above is the detailed content of JavaScript's handling of IE8 compatibility issues. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn