javascript internet-explorer

javascript - "El objeto no admite esta propiedad o método" IE10/11



internet-explorer (1)

Está agregando forEach al objeto de la window , no al objeto que devuelve; estás llamando a $ como una función, no como un constructor. Como está utilizando el modo suelto (aparentemente), this dentro de la llamada a la función es una referencia al objeto global (también accesible como window en los navegadores). Está devolviendo la colección de querySelectorAll sin cambios.

La razón por la que funciona en Chrome es que la colección devuelta por querySelectorAll tiene su propia forEach (esta es una adición bastante reciente).

Para que esto funcione, cuatro opciones:

  1. Devuelva un objeto y agregue forEach a él, copiando los elementos de la colección QSA a ese objeto. P.ej:

    function $(selector) { const result = Array.from(document.querySelectorAll(selector)); result.forEach = Array.prototype.forEach; // Perhaps map, filter, etc.; add in a loop? return result; }

    O en ES5:

    var $ = (function() { var methods = Array.prototype; function $(selector) { var result = methods.slice.call(document.querySelectorAll(selector)); result.forEach = methods.forEach; // Perhaps map, filter, etc.; add in a loop? return result; } return $; })();

  2. Agregue forEach al prototipo NodeList si aún no está allí y use forEach directamente en la colección de querySelectorAll . Por ejemplo:

    if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { // Yes, direct assignment is fine here, no need for `Object.defineProperty` NodeList.prototype.forEach = Array.prototype.forEach; }

    (No hay necesidad de Object.defineProperty arriba, enumerable [sorprendentemente], configurable y writable son todos true en Chrome y Firefox, por lo que podemos hacer una asignación directa como arriba).

    ... y luego, por supuesto, tu $ convierte en nada más que

    function $(selector) { return document.querySelectorAll(selector); }

    (Para empezar. Si desea agregar más funciones, probablemente quiera seguir el camino del # 1).

  3. Devuelve una matriz:

    function $(selector) { return Array.from(document.querySelectorAll(selector)); }

    O en ES5:

    function $(selector) { return Array.prototype.slice.call(document.querySelectorAll(selector)); }

  4. Subclase Array (que no se puede rellenar perfectamente en motores JavaScript anteriores a ES2015) para que pueda agregar sus propias funciones además de las funciones de Array :

    class MyThingy extends Array { // Perhaps further methods here } function $(selector) { return MyThingy.from(document.querySelectorAll(selector)); }

    No hay opción ES5 aquí, necesitaría al menos transpilar y polyfill.

Si va a agregar características más allá de las proporcionadas por Array , me gusta bastante # 4 aparte de que el polyfilling disponible solo es "tan" bueno. Bien puede ser suficiente para sus propósitos.

Con ES6 tomando el control, estoy ansioso por abandonar jQuery y usar JS nativo para las compilaciones de mi sitio web, manteniéndolos rápidos y livianos. También para mejorar mis habilidades de JS, ya que soy uno de los que saltó directamente a jQuery.

Estoy construyendo una pequeña biblioteca para hacer que el javascript usado más común en una función para mantener los archivos pequeños.

function $(elm) { var elm = document.querySelectorAll(elm); this.forEach = function(f) { [].forEach.call(elm, f); } return elm; } function slider() { $(".slider").forEach(function() { alert("Hello"); }); } slider();

Esto funciona muy bien en Chrome, etc., pero en IE10 / 11 obtengo el error

El objeto no admite esta propiedad o método "forEach"

refiriéndose a $ (". slider"). forEach

¿Algunas ideas?