AngularJS 1.3页面不会在IE8中加载

Sam*_*aby 5 javascript internet-explorer-8 angularjs

作为一个有角色的用户,我对这个问题的标题感到不寒而栗,因为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?

Zen*_*rbi 12

有一种方法,虽然它有点粗糙.下面是您需要在角度之前加载的代码,您的应用程序可能会运行.这是垫片/填充物的集合,大部分来自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;
    };
}
Run Code Online (Sandbox Code Playgroud)

如果你有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+"']";


Sam*_*aby 5

根据对问题的评论和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]-->
Run Code Online (Sandbox Code Playgroud)

注意:这通常是一种可怕的做法.如果我们正在努力支持IE8用户,我会选择Zenorbi的答案,因为它允许你只加载一个版本的角度.

  • 这是一个坏主意,因为您不能使用1.3的新功能或1.2的弃用功能. (3认同)

mal*_*kan 5

根据SamHuckabyZenorbi的答案,我想出了一个可接受的解决方案,这是他们的想法和见解的结合,这篇文章如果Internet Explorer那么做其他事情(A How To ...)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>
Run Code Online (Sandbox Code Playgroud)

<!--[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条件注释块,并检查所有的浏览器(和它并不昂贵的操作),因为我最近发现Safari有问题String.prototype.startsWith()

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