Reputation: 511
My scenario: I'm trying to mask some input fields using jQuery Inputmask Plugin. It is ok on Chrome, Opera, Safari, IE10, Firefox, but not on IE8!
I created a dummy page to test if other scripts was interfering, but isn't the case.
HTML
<!doctype html>
<html>
<head>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="inputmask/inputmask.js"></script>
<script type="text/javascript" src="inputmask/jquery.inputmask.js"></script>
<script type="text/javascript" src="inputmask/inputmask.extensions.js"></script>
<script type="text/javascript" src="inputmask/inputmask.dependencyLib.jquery.js"></script>
<script type="text/javascript" src="inputmask/inputmask.numeric.extensions.js"></script>
<script type="text/javascript" src="inputmask/inputmask.phone.extensions.js"></script>
<script type="text/javascript" src="inputmask/inputmask.regex.extensions.js"></script>
<!--[if lte IE 8]>
<script type="text/javascript" src="js/ie8customscripts.js"></script>
<link href="css/ie8customstyles.css" rel="stylesheet" type="text/css">
<![endif]-->
<!--[if IE 9]>
<script type="text/javascript" src="js/ie9customscripts.js"></script>
<link href="css/ie9customstyles.css" rel="stylesheet" type="text/css">
<![endif]-->
</head>
<body>
cpf<br/><input id="cpf" type="text"></input>
cnpj<br/><input id="cnpj" type="text"></input>
</body>
</html>
JS (ie8customscripts.js)
$(function(){
$("#cpf").inputmask("99-9999999"); //static mask
$("#cnpj").inputmask({"mask": "(999) 999-9999"}); //specifying options
});
In my actual pages, i was using data-
attributes to set the mask, which obviously didn't worked on IE8, so i tried to do this way.
Here's the exact line that throws the error (it is thrown about 20 times).
Until where I know, it was supposed to work on IE8, right?
Upvotes: 0
Views: 1620
Reputation: 1802
I do not know which version of jQuery and jquery.inputmask do you use but I had the same trouble yesterday with jQuery 1.8.3 and jquery.inputmask 3.3.x version running on IE8. So I did some investigation on jquery.inputmask and I have realized that it relies on jQuery.inArray method feeding both with string and array parameters as well. I have checked jQuery 1.8.3, 1.10.2, 1.11.3, 1.12.4 versions as well and the situation was exactly the same.
Here is the jQuery implementation of it's inArray method:
inArray: function( elem, arr, i ) {
var len;
if ( arr ) {
if ( Array.prototype.indexOf ) {
return Array.prototype.indexOf.call( arr, elem, i );
}
len = arr.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays
if ( i in arr && arr[ i ] === elem ) {
return i;
}
}
}
return -1;
},
Yo can see if the Array.prototype.indexOf exists the native implementation will be executed. So there is no problem when IE11, Chrome, Firefox because they have native implementation for Array.prototype.indexOf which is missing from IE8.
So in IE8 this part of code will be executed:
len = arr.length;
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
for ( ; i < len; i++ ) {
// Skip accessing in sparse arrays
if ( i in arr && arr[ i ] === elem ) {
return i;
}
}
this code does the same thing what Antiga suggested - so in your code you would use $.inArray as well
But calling inArray with string parameters (as jquery.inputmask does) instead of array cause exception at the i in arr line that in operation is invalid for string. That is why I have used the following override (after including jquery.js of course) in my application (at my company IE8 is still used):
$.inArray = function (elem, arr, i) {
var len;
if (arr) {
if (typeof arr === "string") {
// this is my extension
return arr.indexOf(elem, i);
} else {
if (Array.prototype.indexOf) {
return Array.prototype.indexOf.call(arr, elem, i);
}
len = arr.length;
i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0;
for (; i < len; i++) {
// Skip accessing in sparse arrays
if (i in arr && arr[ i ] === elem) {
return i;
}
}
}
}
return -1;
};
This solved all of the problem related to jQuery 1.8+, jquery.inputmask 3.3.x and IE8 cooperation.
Upvotes: 1
Reputation: 2274
IE8 and below doesn't support indexOf
. You can polyfill it yourself, but you are modifying the prototype of a native object and that's super shiesty. But hey, that's the name of the game with IE.
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;
};
}
credit: @NickCraver Why doesn't indexOf work on an array IE8?
Upvotes: 1