Why doesn't indexOf work on an array IE8?
The below function works fine on Opera, Firefox and Chrome. However, in IE8 it fails on the if ( allowed.indexOf(ext[1]) == -1)
part.
Does anyone know why? Is there any obvious mistake?
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');
va开发者_开发问答r 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!');
}
}
Versions of IE before IE9 don't have an .indexOf()
function for Array, to define the exact spec version, run this before trying to use it:
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;
};
}
This is the version from MDN, used in Firefox/SpiderMonkey. In other cases such as IE, it'll add .indexOf()
in the case it's missing... basically IE8 or below at this point.
If you're using jQuery, you can use $.inArray() instead.
If you're using jQuery and want to keep using indexOf without worrying about compatibility issues, you can do this :
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(val) {
return jQuery.inArray(val, this);
};
}
This is helpful when you want to keep using indexOf
but provide a fallback when it's not available.
For a really thorough explanation and workaround, not only for indexOf but other array functions missing in IE check out the StackOverflow question Fixing JavaScript Array functions in Internet Explorer (indexOf, forEach, etc.)
Please careful with $.inArray if you want to use it. I just found out that the $.inArray is only works with "Array", not with String. That's why this function will not working in IE8!
The jQuery API make confusion
The $.inArray() method is similar to JavaScript's native .indexOf() method in that it returns -1 when it doesn't find a match. If the first element within the array matches value, $.inArray() returns 0
--> They shouldn't say it "Similar". Since indexOf support "String" also!
The problem
IE<=8 simply doesn't have an indexOf()
method for arrays.
The solution
If you need indexOf
in IE<=8, you should consider using the following polyfill, which is recommended at the 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});
You can use this to replace the function if it doesn't exist:
<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>
精彩评论