AngularJS 1.3 page not loading in IE8

As an angular user, I also flinch at the name of this question, because IE8 is the embodiment of evil and should be crushed like a mad dog.

which I was wondering if someone else ran into the problem of loading angular 1.3 in IE8 and hacking the page before loading and just reporting an error: Object Expected in if condition using isArray (). (isArray () is also found in angular 1.2, so it bothers me that it works there, but not in 1.3)

So, so that everyone understands my reasons, my company recently took a step without supporting IE8 in the new development. But our new interface should support ONLY IE8 on the initial landing page so that users can access our old software that supports IE8. I was hoping I could use 1.3, and just write some small settings for the landing page until it leaves IE8.

The general question is: can angular 1.3 be used with IE8 at all, or will I be forced to use 1.2 until we completely remove IE8 support?

+5
source share
6 answers

There is a way, although it's a little rude. Below is the code that needs to be downloaded before angular and your application can run. This is a gasket / polypol assembly, mainly from the Mozilla Developer Network, some of them.

Please note that this allows the launch of AngularJS, but does not update the IE8 JS environment. Therefore, things like somePromise.catch(...) will not work, you should write somePromise["catch"](...) .

 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement) { if (this.length === 0) { return -1; } var n = 0; if (arguments.length > 1) { n = Number(arguments[1]); if (isNaN(n)) { n = 0; } else if (n !== 0 && n !== Infinity && n !== -Infinity) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } if (n >= this.length) { return -1; } var k = n >= 0 ? n : Math.max(this.length - Math.abs(n), 0); while (k < this.length) { if (k in this && this[k] === searchElement) { return k; } ++k; } return -1; }; } if (!Array.prototype.filter) { Array.prototype.filter = function(fun/*, thisArg*/) { if (this === undefined || this === null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (typeof fun !== 'function') { throw new TypeError(); } var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; if (fun.call(thisArg, val, i, t)) { res.push(val); } } } return res; }; } if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; } if (!Array.prototype.every) { Array.prototype.every = function(callbackfn, thisArg) { 'use strict'; var T, k; if (this == null) { throw new TypeError('this is null or not defined'); } var O = Object(this); var len = O.length >>> 0; if (typeof callbackfn !== 'function') { throw new TypeError(); } if (arguments.length > 1) { T = thisArg; } k = 0; while (k < len) { var kValue; if (k in O) { kValue = O[k]; var testResult = callbackfn.call(T, kValue, k, O); if (!testResult) { return false; } } k++; } return true; }; } if (!Object.create) { Object.create = (function() { var Object = function() {}; return function (prototype) { if (arguments.length > 1) { throw new Error('Second argument not supported'); } if (typeof prototype != 'object') { throw new TypeError('Argument must be an object'); } Object.prototype = prototype; var result = new Object(); Object.prototype = null; return result; }; })(); } if (!Array.prototype.forEach) { Array.prototype.forEach = function(fun /*, thisArg */) { if (this === void 0 || this === null) throw new TypeError(); var t = Object(this); var len = t.length >>> 0; if (typeof fun !== "function") throw new TypeError(); var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; ++i) { if (i in t) fun.call(thisArg, t[i], i, t); } }; } if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^\s+|\s+$/gm, ''); }; } (function() { //$http uses onload instead of onreadystatechange. Need shimming as IE8 doesn't have onload. if (new XMLHttpRequest().onload === undefined) { var orig = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function() { var self = this; if (!this.onreadystatechange && this.onload) { this.onreadystatechange = function() { if (self.readyState === 4) { self.onload(); } }; } orig.apply(self, arguments); }; } })(); if (!Date.now) { Date.now = function() { return new Date().getTime(); }; } if (!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if (typeof this !== "function") { throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function() { }, fBound = function() { return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; } if (!Object.keys) { Object.keys = function(object) { var keys = []; for (var o in object) { if (object.hasOwnProperty(o)) { keys.push(o); } } return keys; }; } if (!Object.getPrototypeOf) { Object.getPrototypeOf = function(object) { return object.__proto__ || object.constructor.prototype; }; } 

If you have angular-bootstrap, you also need to β€œplan” the angular.min.js file because angular -boostrap uses {in: someCondition} , but due to the older JS in runtime, the keyword is reserved and will not generate the code.

Find: var e=(b?"s":'((l&&l.hasOwnProperty("'+a+'"))?l:s)')+"."+a;

Replace: var e=(b?"s":'((l&&l.hasOwnProperty("'+a+'"))?l:s)')+"['"+a+"']";

+12
source

In the comments on the question, and the answer by Zenorbi, Angular 1.3 does NOT load correctly in IE8. It was never intended to continue to work in IE8, so this should not be surprising.

I actually came up with a simple workaround that will make the page load time a bit slower for any IE8 users, which is an acceptable loss for me.

using this code, I can simply download 1.3 by default, and if any IE8 users load the page, it will just download Angular 1.2 directly, just overwrite any duplicated code:

 <script type="text/javascript" src="target/libraries/angular.min.js"></script> <!--[if lt IE 9]> <script type="text/javascript" src="target/libraries/angular-1.2.min.js"></script> <![endif]--> <script type="text/javascript" src="target/libraries/angular-route.min.js"></script> <!--[if lt IE 9]> <script type="text/javascript" src="target/libraries/angular-route-1.2.min.js"></script> <![endif]--> 

note . This is a terrible practice in general. If we make more efforts to support IE8 users, I would go with Zenorbi's answer, as it only allows you to download one version of angular.

+5
source

Based on the answers from SamHuckaby and Zenorbi, I found an acceptable solution that is a combination of their ideas and ideas from this article IF Internet Explorer THEN Do Something Else (A How To ...) from Phil Nash :

  <!--[if !IE]>--> <script src="/ui/resources/webjars/angularjs/1.4.0/angular.js"></script> <script src="/ui/resources/webjars/angularjs/1.4.0/angular-route.js"></script> <!--<![endif]--> <!--[if gt IE 8]> <script src="/ui/resources/webjars/angularjs/1.4.0/angular.js"></script> <script src="/ui/resources/webjars/angularjs/1.4.0/angular-route.js"></script> <![endif]--> <!--[if lt IE 9]> <script type="text/javascript" src="/ui/resources/lib/angularjs/1.2.28/angular.js"></script> <script type="text/javascript" src="/ui/resources/lib/angularjs/1.2.28/angular-route.js"></script> <![endif]--> <script type="text/javascript" src="webjars/es5-shim/4.0.6/es5-shim.js"></script> <script type="text/javascript" src="webjars/es6-shim/0.20.2/es6-shim.js"></script> 

<!--[if !IE]>-->...<!--<![endif]--> - The conditional comment will be evaluated using IE , but the scripts inside will not be loaded by IE and loaded by all other browsers

<!--[if gt IE 8]>...<![endif]--> - The conditional comment will be evaluated using IE , and if it is larger than IE 8, scripts will be loaded

<!--[if lt IE 9]>...<![endif]--> - The conditional comment will be evaluated using IE , and if it is smaller than IE 9, the scripts will be loaded.

Both es5-shim and es6-shim should be excluded from the IE8 conditional comment block and marked by all browsers (and this is not an expensive operation) since I recently discovered that Safari has problems with String.prototype.startsWith()

Yes, we have some duplication of code inside the first and second conditional comments (and this cannot be solved otherwise), but we have zero unwanted scripts loaded , and we can close our task here.

+5
source

From Angular Migration Docs for Developers :

Note. AngularJS 1.3 reduces support for IE8. Find out more about this in our blog. AngularJS 1.2 will continue to support IE8, but the core team does not plan to spend time resolving issues specific to IE8 or earlier.

+1
source

Github user @fergaldoyle supports a repo that combines shiming / polyfill and other patch strategies to maintain compatibility.

This can be a viable strategy for many solution providers.

+1
source

I tried answering L0lander (which was my preferred), but when using an older version of angular, other scripts complained, and this ended up not working. So, I checked the statistics on my website, and 0.2% used only IE8 or less, and I will not root for such a small audience, so I just added a message asking for an update to IE8 or less.

Add the following code immediately after the body tag to all of your pages:

 <!--[if lt IE 9]> <div style="text-align: center; font-size: 22px; padding: 20px; background-color: #d14c4c; color: #f3e3e3;">Your version of Internet Explorer is too old for this site to function properly.<br>Please <a href="https://www.google.com/search?q=update+internet+explorer" target="_blank" style="text-decoration: underline; color: #76c880">click here</a> to upgrade to a newer version.</div> <![endif]--> 
0
source

Source: https://habr.com/ru/post/1207055/


All Articles