Почему indexOf не работает с массивом IE8?

Эта функция отлично работает в Opera, Firefox и Chrome. Однако в IE8 он не работает в части if ( allowed.indexOf(ext[1]) == -1).

Кто-нибудь знает, почему? Есть ли очевидная ошибка?

function CheckMe() {
    var allowed = new Array('docx','xls','xlsx', 'mp3', 'mp4', '3gp', 'sis', 'sisx', 'mp3', 'wav', 'mid', 'amr', 'jpg', 'gif', 'png', 'jpeg', 'txt', 'pdf', 'doc', 'rtf', 'thm', 'rar', 'zip', 'htm', 'html', 'css', 'swf', 'jar', 'nth', 'aac', 'cab', 'wgz');
    var fileinput=document.getElementById('f');
    var ext = fileinput.value.toLowerCase().split('.');
    if ( allowed.indexOf(ext[1]) == -1) 
    {
        document.getElementById('uploadsec').innerHTML = document.getElementById('uploadsec').innerHTML;
        alert('This file type is not allowed!');
    }
}

Ответ 1

Версии IE перед IE9 не имеют функции .indexOf() для Array, чтобы определить точная версия спецификации, запустите это, прежде чем пытаться его использовать:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Это версия из MDN, используемая в Firefox/SpiderMonkey. В других случаях, таких как IE, он добавит .indexOf() в случае, если он отсутствует... в основном IE8 или ниже на этом этапе.

Ответ 2

Если вы используете jQuery, вы можете использовать $. inArray().

Ответ 3

Если вы используете jQuery и хотите продолжать использовать indexOf, не беспокоясь о проблемах совместимости, вы можете сделать это:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(val) {
        return jQuery.inArray(val, this);
    };
}

Это полезно, если вы хотите продолжать использовать indexOf, но предоставить резервную копию, когда она недоступна.

Ответ 5

Пожалуйста, будьте осторожны с $.inArray, если вы хотите его использовать. Я только узнал, что $.inArray работает только с "Array", а не с String. Вот почему эта функция не будет работать в IE8!

API jQuery создает путаницу

Метод $.inArray() похож на родной язык .indexOf() в том, что он возвращает -1, когда он не находит совпадения. Если первый элемент внутри массива соответствует значению, $.inArray() возвращает 0

- > Они не должны говорить "похоже". Так как indexOf также поддерживает "String"!

Ответ 6

Проблема

IE <= 8 просто не имеет метода indexOf() для массивов.


Решение

Если вам нужно indexOf в IE <= 8, вы должны рассмотреть возможность использования следующего polyfill, который рекомендуется в MDN:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(searchElement, fromIndex) {
        var k;
        if (this == null) {
            throw new TypeError('"this" is null or not defined');
        }
        var o = Object(this);
        var len = o.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = +fromIndex || 0;
        if (Math.abs(n) === Infinity) {
            n = 0;
        }
        if (n >= len) {
            return -1;
        }
        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
        while (k < len) {
            if (k in o && o[k] === searchElement) {
                return k;
            }
            k++;
        }
        return -1;
    };
}

Minified:

Array.prototype.indexOf||(Array.prototype.indexOf=function(r,t){var n;if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if(0===i)return-1;var a=+t||0;if(Math.abs(a)===1/0&&(a=0),a>=i)return-1;for(n=Math.max(a>=0?a:i-Math.abs(a),0);i>n;){if(n in e&&e[n]===r)return n;n++}return-1});

Ответ 7

Вы можете использовать это, чтобы заменить функцию, если она не существует:

<script>
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++) {
            if (from in this && this[from] === elt)
                return from;
        }
        return -1;
    };
}
</script>