javascript ejemplo - ¿Por qué no funciona indexOf en un array IE8?




contar repetidos (7)

La siguiente función funciona bien en Opera, Firefox y Chrome. Sin embargo, en IE8 falla en la parte if ( allowed.indexOf(ext[1]) == -1) .

¿Alguien sabe por qué? ¿Hay algún error obvio?

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!');
    }
}

Answers

Las versiones de IE antes de IE9 no tienen una función .indexOf() para Array, para definir la versión de la especificación exacta , ejecute esto antes de intentar usarla:

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;
  };
}

Esta es la versión de MDN , utilizada en Firefox / SpiderMonkey. En otros casos, como IE, agregará .indexOf() en el caso de que falte ... básicamente IE8 o inferior en este punto.


Puedes usar esto para reemplazar la función si no existe:

<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>

Si está utilizando jQuery y desea seguir usando indexOf sin preocuparse por los problemas de compatibilidad, puede hacer esto:

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

Esto es útil cuando desea seguir utilizando indexOf pero proporciona un respaldo cuando no está disponible.


Por favor tenga cuidado con $ .inArray si quiere usarlo. Acabo de descubrir que $ .inArray solo funciona con "Array", no con String. Es por eso que esta función no funcionará en IE8!

La API de jQuery crea confusión.

El método $ .inArray () es similar al método nativo .indexOf () de JavaScript en que devuelve -1 cuando no encuentra una coincidencia. Si el primer elemento dentro de la matriz coincide con el valor, $ .inArray () devuelve 0

-> No deberían decirlo "Similar". Desde indexOf soporte "String" también!


El problema

IE <= 8 simplemente no tiene un método .indexOf() para los arreglos.

La solución

Si necesita indexOf en IE <= 8, debe considerar el uso del siguiente polyfill , que se .indexOf() :

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;
    };
}

Minificado

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});


Otros han respondido "cómo" y han citado espec. Aquí está la verdadera historia de "por qué no <script/> ", después de muchas horas investigando informes de errores y listas de correo.

HTML 4

HTML 4 está basado en SGML .

SGML tiene algunas shorttags , como <BR// <B>text</> , <B/text/ , o <OL<LI>item</LI</OL> . XML toma la primera forma, redefine la terminación como ">" (SGML es flexible), de modo que se convierte en <BR/> .

Sin embargo, HTML no se redefinió, por lo que <SCRIPT/> debería significar <SCRIPT>> .
(Sí, el '>' debe ser parte del contenido, y la etiqueta aún no está cerrada.)

Obviamente, esto es incompatible con XHTML y romperá muchos sitios (para cuando los navegadores estuvieran lo suficientemente maduros como para preocuparse por esto ), por lo que nadie implementó las etiquetas rápidas y la especificación desaconseja .

Efectivamente, todas las etiquetas de "finalización automática" son etiquetas con etiqueta de final opcional en analizadores técnicamente no conformes y, de hecho, son inválidas. Fue W3C el que creó este truco para ayudar a la transición a XHTML haciéndolo HTML-compatible .

Y la etiqueta final de <script> no es opcional .

La etiqueta de "finalización automática" es un truco en HTML 4 y no tiene sentido.

HTML 5

HTML5 tiene cinco tipos de etiquetas y solo las etiquetas "nulas" y "extranjeras" pueden cerrarse automáticamente .

Debido a que <script> no es nulo ( puede tener contenido) y no es ajeno (como MathML o SVG), <script> no puede cerrarse automáticamente, independientemente de cómo lo use.

¿Pero por qué? ¿No pueden considerarlo extranjero, hacer un caso especial o algo así?

HTML 5 pretende ser backward-compatible con backward-compatible de las implementaciones de HTML 4 y XHTML 1. No está basado en SGML o XML; Su sintaxis se ocupa principalmente de documentar y unir las implementaciones. (Esta es la razón por la que <br/> <hr/> etc. son válidos HTML 5 a pesar de ser HTML4 no válido).

El <script> cierre automático es una de las etiquetas donde las implementaciones solían diferir. Solía ​​trabajar en Chrome, Safari y Opera ; que yo sepa, nunca funcionó en Internet Explorer o Firefox.

Esto se discutió cuando HTML 5 estaba siendo redactado y fue rechazado porque breaks compatibility browser . Las páginas web que cierran automáticamente la etiqueta de script pueden no mostrarse correctamente (si las hay) en los navegadores antiguos. Hubo otras propuestas , pero tampoco pueden resolver el problema de compatibilidad.

Después de que se publicara el borrador, WebKit actualizó el analizador para que estuviera en conformidad.

El <script> cierre automático no ocurre en HTML 5 debido a la compatibilidad con versiones anteriores de HTML 4 y XHTML 1.

XHTML 1 / XHTML 5

Cuando realmente se sirve como XHTML, <script/> está realmente cerrado, como han indicado otras respuestas .

Excepto que la especificación dice que debería haber funcionado cuando se sirvió como HTML:

Los documentos XHTML ... pueden estar etiquetados con el tipo de medios de Internet "text / html" [RFC2854], ya que son compatibles con la mayoría de los navegadores HTML.

¿Entonces qué pasó?

La gente le pidió a Mozilla que dejara que Firefox analizara documentos conformes como XHTML independientemente del encabezado de contenido especificado (conocido como rastreo de contenido ). Esto hubiera permitido los scripts de cierre automático, y la detección del contenido era necesaria de todos modos porque los servidores de alojamiento web no eran lo suficientemente maduros para servir el encabezado correcto; IE era bueno en eso .

Si la primera guerra de navegadores no terminó con IE 6, XHTML también podría haber estado en la lista. Pero sí terminó. Y IE 6 tiene un problema con XHTML. De hecho, IE no era compatible con el tipo MIME correcto, lo que obligaba a todos a usar text/html para XHTML porque IE tenía una importante participación de mercado durante toda una década.

Y también la inhalación de contenido puede ser realmente mala y la gente dice que se debe detener .

Finalmente, resulta que el W3C no significa que XHTML sea sniffable : el documento es a la vez , HTML y XHTML, y reglas de Content-Type . Se puede decir que se mantuvieron firmes en "solo seguir nuestras especificaciones" e ignorar lo que era práctico . Un error que continued en las últimas versiones de XHTML.

De todos modos, esta decisión resolvió el asunto para Firefox. Pasaron 7 años antes de que naciera Chrome; No hubo otro navegador significativo. Así se decidió.

La especificación del doctype solo no desencadena el análisis XML debido a las siguientes especificaciones.





javascript internet-explorer internet-explorer-8 indexof