[英]AngularJS 1.3 page won't load in IE8
作為一個有角色的用戶,我對這個問題的標題感到不寒而栗,因為IE8是邪惡的化身,應該像狂犬病一樣被放下。
話雖這么說,我想知道是否有其他人遇到過在IE8中加載Angular 1.3的問題,並且在加載之前頁面中斷並且只報告錯誤: Object Expected
在使用isArray()函數的if條件下出現。 (isArray()也可以在Angular 1.2中找到,所以它讓我感到困惑,它在那里工作但在1.3中沒有
為了讓每個人都理解我的理由,我的公司最近采取了不再支持IE8進行新開發的步驟。 但是我們的新UI只需要在初始登錄頁面上支持IE8,這樣用戶仍然可以訪問支持IE8的舊軟件。 我希望我可以使用1.3,只是為着陸頁寫下小調整,直到它也從IE8下面出來。
首要問題:是否可以將Angular 1.3與IE8一起使用,或者在我們完全刪除IE8支持之前,我是否會被迫使用1.2?
有一種方法,雖然它有點粗糙。 下面是您需要在角度之前加載的代碼,您的應用程序可能會運行。 這是墊片/填充物的集合,大部分來自Mozilla Developer Network。
請注意,這只允許AngularJS運行,它不會更新IE8的JS運行時。 所以像somePromise.catch(...)
這樣的東西不起作用,你必須寫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;
};
}
如果你有angular-bootstrap,你還需要“修補”angular.min.js文件,因為angular-boostrap使用{in: someCondition}
,但由於舊的JS運行時, in
關鍵字是保留的,並且會在代碼生成。
查找: var e=(b?"s":'((l&&l.hasOwnProperty("'+a+'"))?l:s)')+"."+a;
替換: var e=(b?"s":'((l&&l.hasOwnProperty("'+a+'"))?l:s)')+"['"+a+"']";
根據對問題的評論和Zenorbi的回答,Angular 1.3不再能夠在IE8中正確加載。 它從未被設計為繼續在IE8中工作,所以這不應該是一個驚喜。
我實際上想出了一個簡單的解決方法,它會使任何IE8用戶的頁面加載時間稍微慢一些,這對我來說是可以接受的。
使用此代碼,我可以簡單地加載1.3,如果任何IE8用戶加載頁面,它將直接加載角度1.2,只需覆蓋任何重復的代碼:
<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]-->
注意 :這通常是一種可怕的做法。 如果我們正在努力支持IE8用戶,我會選擇Zenorbi的答案,因為它允許你只加載一個版本的角度。
根據SamHuckaby和Zenorbi的答案,我想出了一個可接受的解決方案,這是他們的想法和見解的結合,這篇文章如果Internet Explorer那么做其他事情(如何...)由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]-->
- 條件評論將由IE
評估,但其中的腳本將不會被IE
加載並且將會被所有其他瀏覽器加載
<!--[if gt IE 8]>...<![endif]-->
- 條件評論將由IE
評估,如果大於IE 8,腳本將被加載
<!--[if lt IE 9]>...<![endif]-->
- 條件評論將由IE
評估,如果小於IE 9,將加載腳本。
es5-shim
和es6-shim
都應該從IE8
條件注釋塊中刪除並由所有瀏覽器檢查(並且它不是昂貴的操作)因為我最近發現Safari
有String.prototype.startsWith()
問題
是的,我們在第一個和第二個條件注釋中有一些代碼重復(並且它不能以不同的方式解決)但是我們沒有加載任何不需要的腳本 ,我們可以在這里關閉我們的任務。
來自Angular Developer Guide遷移文檔 :
注意:AngularJS 1.3正在放棄對IE8的支持。 在我們的博客上閱讀更多相關信息。 AngularJS 1.2將繼續支持IE8,但核心團隊並不打算花時間解決IE8或更早版本的特定問題。
我嘗試了L0lander的答案(這是我首選的答案),但是當使用較舊的角度版本時,其他腳本會抱怨,並且最終無法正常工作。 所以,我檢查了我的網站的統計數據,0.2%只使用IE8或更低,我不會讓自己頭疼這么小的人群,所以我只是添加了一條消息,要求IE8或更低版本的用戶升級。
在body
標簽之后將以下代碼添加到您的所有頁面:
<!--[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]-->
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.