Estoy usando el siguiente código, pero falla en IE. El mensaje es:
No se puede obtener el valor de la propiedad 'agregar': el objeto es nulo o no está definido "
Supongo que esto es solo un problema de soporte de IE. ¿Cómo haría que funcione el siguiente código en IE?
¿Algunas ideas?
var img = new Image();
img.src = '/image/file.png';
img.title = 'this is a title';
img.classList.add("profilePic");
var div = document.createElement("div");
div.classList.add("picWindow");
div.appendChild(img);
content.appendChild(div);
javascript
internet-explorer
Wesley
fuente
fuente
classList
.querySelector
debería serloclassList
. En segundo lugar, el.remove
método contiene una RegExp innecesaria, cuyo uso -como ha reconocido- introduce un error. Debido a que ya tiene espacios prefijados y con sufijos, un simple.replace(' ' + className + ' ', ' ')
es suficiente (además, la observación "Un className válido no debe contener ningún carácter especial de expresiones regulares" es incorrecta, consulte las especificaciones (también es cierto para HTML4))Respuestas:
La
classList
propiedad no es compatible con IE9 y versiones anteriores. Sin embargo, IE10 + lo admite.Úselo en su
className += " .."
lugar. Nota: No omita el espacio: los nombres de las clases deben agregarse en una lista separada por espacios en blanco.var img = new Image(); img.src = '/image/file.png'; img.title = 'this is a title'; img.className += " profilePic"; // Add profilePic class to the image var div = document.createElement("div"); div.className += " picWindow"; // Add picWindow class to the div div.appendChild(img); content.appendChild(div);
fuente
className
atributo siempre existe. Se inicializa en una cadena vacía. Para facilitar el mantenimiento del código,+=
se recomienda usar para agregar nombres de clases.className
propiedad de un elemento DOM es lectura-escritura.Como han mencionado otros,
classList
no es compatible con IE9 y versiones anteriores. Además de la alternativa de Alex anterior, hay un par de polyfills que pretenden ser un reemplazo directo, es decir, simplemente inclúyalos en su página e IE debería funcionar (¡las famosas últimas palabras!).https://github.com/eligrey/classList.js/blob/master/classList.js
https://gist.github.com/devongovett/1381839
fuente
/** * Method that checks whether cls is present in element object. * @param {Object} ele DOM element which needs to be checked * @param {Object} cls Classname is tested * @return {Boolean} True if cls is present, false otherwise. */ function hasClass(ele, cls) { return ele.getAttribute('class').indexOf(cls) > -1; } /** * Method that adds a class to given element. * @param {Object} ele DOM element where class needs to be added * @param {Object} cls Classname which is to be added * @return {null} nothing is returned. */ function addClass(ele, cls) { if (ele.classList) { ele.classList.add(cls); } else if (!hasClass(ele, cls)) { ele.setAttribute('class', ele.getAttribute('class') + ' ' + cls); } } /** * Method that does a check to ensure that class is removed from element. * @param {Object} ele DOM element where class needs to be removed * @param {Object} cls Classname which is to be removed * @return {null} Null nothing is returned. */ function removeClass(ele, cls) { if (ele.classList) { ele.classList.remove(cls); } else if (hasClass(ele, cls)) { ele.setAttribute('class', ele.getAttribute('class').replace(cls, ' ')); } }
fuente
ele.getAttribute('class')
devuelto nulo en algunos casos (¿tal vez si el atributo de clase aún no está configurado?) - una simple declaración if lo resolvió.mira esto
Object.defineProperty(Element.prototype, 'classList', { get: function() { var self = this, bValue = self.className.split(" ") bValue.add = function (){ var b; for(i in arguments){ b = true; for (var j = 0; j<bValue.length;j++) if (bValue[j] == arguments[i]){ b = false break } if(b) self.className += (self.className?" ":"")+arguments[i] } } bValue.remove = function(){ self.className = "" for(i in arguments) for (var j = 0; j<bValue.length;j++) if(bValue[j] != arguments[i]) self.className += (self.className?" " :"")+bValue[j] } bValue.toggle = function(x){ var b; if(x){ self.className = "" b = false; for (var j = 0; j<bValue.length;j++) if(bValue[j] != x){ self.className += (self.className?" " :"")+bValue[j] b = false } else b = true if(!b) self.className += (self.className?" ":"")+x } else throw new TypeError("Failed to execute 'toggle': 1 argument required") return !b; } return bValue; }, enumerable: false })
¡y classList funcionará!
document.getElementsByTagName("div")[0].classList ["aclass"] document.getElementsByTagName("div")[0].classList.add("myclass") document.getElementsByTagName("div")[0].className "aclass myclass"
¡eso es todo!
fuente
En IE 10 y 11, la propiedad classList se define en HTMLElement.prototype.
Para que funcione en elementos SVG, la propiedad debe definirse en Element.prototype, como lo ha sido en otros navegadores.
Una solución muy pequeña sería copiar el propertyDescriptor exacto de HTMLElement.prototype a Element.prototype:
if (!Object.getOwnPropertyDescriptor(Element.prototype,'classList')){ if (HTMLElement&&Object.getOwnPropertyDescriptor(HTMLElement.prototype,'classList')){ Object.defineProperty(Element.prototype,'classList',Object.getOwnPropertyDescriptor(HTMLElement.prototype,'classList')); } }
Element.prototype.classList = HTMLElement.prototype.classList
que arrojaráInvalid calling object
Para IE 8 y 9, use el siguiente código, también incluí un polyfill (minificado) para Array.prototype.indexOf, porque IE 8 no lo admite de forma nativa (fuente de polyfill: Array.prototype.indexOf
//Polyfill Array.prototype.indexOf Array.prototype.indexOf||(Array.prototype.indexOf=function (value,startIndex){'use strict';if (this==null)throw new TypeError('array.prototype.indexOf called on null or undefined');var o=Object(this),l=o.length>>>0;if(l===0)return -1;var n=startIndex|0,k=Math.max(n>=0?n:l-Math.abs(n),0)-1;function sameOrNaN(a,b){return a===b||(typeof a==='number'&&typeof b==='number'&&isNaN(a)&&isNaN(b))}while(++k<l)if(k in o&&sameOrNaN(o[k],value))return k;return -1}); // adds classList support (as Array) to Element.prototype for IE8-9 Object.defineProperty(Element.prototype,'classList',{ get:function(){ var element=this,domTokenList=(element.getAttribute('class')||'').replace(/^\s+|\s$/g,'').split(/\s+/g); if (domTokenList[0]==='') domTokenList.splice(0,1); function setClass(){ if (domTokenList.length > 0) element.setAttribute('class', domTokenList.join(' '); else element.removeAttribute('class'); } domTokenList.toggle=function(className,force){ if (force!==undefined){ if (force) domTokenList.add(className); else domTokenList.remove(className); } else { if (domTokenList.indexOf(className)!==-1) domTokenList.splice(domTokenList.indexOf(className),1); else domTokenList.push(className); } setClass(); }; domTokenList.add=function(){ var args=[].slice.call(arguments) for (var i=0,l=args.length;i<l;i++){ if (domTokenList.indexOf(args[i])===-1) domTokenList.push(args[i]) }; setClass(); }; domTokenList.remove=function(){ var args=[].slice.call(arguments) for (var i=0,l=args.length;i<l;i++){ if (domTokenList.indexOf(args[i])!==-1) domTokenList.splice(domTokenList.indexOf(args[i]),1); }; setClass(); }; domTokenList.item=function(i){ return domTokenList[i]; }; domTokenList.contains=function(className){ return domTokenList.indexOf(className)!==-1; }; domTokenList.replace=function(oldClass,newClass){ if (domTokenList.indexOf(oldClass)!==-1) domTokenList.splice(domTokenList.indexOf(oldClass),1,newClass); setClass(); }; domTokenList.value = (element.getAttribute('class')||''); return domTokenList; } });
fuente
)
.En Explorer 11, classList.add funciona solo con valores individuales.
Element.classList.add("classOne", "classTwo");
En este caso, Explorer agrega solo la primera clase e ignora la segunda. Entonces necesito hacer:
Element.classList.add("classOne"); Element.classList.add("classTwo");
fuente
classList
no es compatible con IE <9. Use jQuery.addClass o un polyfill como el de https://developer.mozilla.org/en-US/docs/Web/API/Element/classListfuente
classList
funcionalidad