繁体   English   中英

AngularJS 1.3页面不会在IE8中加载

[英]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的答案,因为它允许你只加载一个版本的角度。

根据SamHuckabyZenorbi的答案,我想出了一个可接受的解决方案,这是他们的想法和见解的结合,这篇文章如果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-shimes6-shim都应该从IE8条件注释块中删除并由所有浏览器检查(并且它不是昂贵的操作)因为我最近发现SafariString.prototype.startsWith()问题

是的,我们在第一个和第二个条件注释中有一些代码重复(并且它不能以不同的方式解决)但是我们没有加载任何不需要的脚本 ,我们可以在这里关闭我们的任务。

来自Angular Developer Guide迁移文档

注意:AngularJS 1.3正在放弃对IE8的支持。 在我们的博客上阅读更多相关信息。 AngularJS 1.2将继续支持IE8,但核心团队并不打算花时间解决IE8或更早版本的特定问题。

Github用户@fergaldoyle 维护一个包含shiming / polyfill和其他补丁策略的repo ,以保持兼容性。

这可能是许多解决方案提供商的可行策略

我尝试了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM