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:
-
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 $; })();
-
Agregue
forEach
al prototipoNodeList
si aún no está allí y useforEach
directamente en la colección dequerySelectorAll
. 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
ywritable
son todostrue
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 quefunction $(selector) { return document.querySelectorAll(selector); }
(Para empezar. Si desea agregar más funciones, probablemente quiera seguir el camino del # 1).
-
Devuelve una matriz:
function $(selector) { return Array.from(document.querySelectorAll(selector)); }
O en ES5:
function $(selector) { return Array.prototype.slice.call(document.querySelectorAll(selector)); }
-
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 deArray
: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?