Używam następującego kodu, ale nie działa w IE. Wiadomość brzmi:
Nie można pobrać wartości właściwości „add”: obiekt jest pusty lub niezdefiniowany ”
Zakładam, że to tylko problem z obsługą IE. Jak sprawić, by następujący kod działał w IE?
Jakieś pomysły?
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
źródło
źródło
classList
kilka polyfillów .querySelector
powinno byćclassList
. Po drugie,.remove
metoda zawiera niepotrzebne wyrażenie RegExp, którego użycie - jak przyznałeś - wprowadza błąd. Bo już przed- i sufiksem przestrzenie, proste.replace(' ' + className + ' ', ' ')
wystarczy (ponadto uwaga „Poprawna className nie powinny zawierać żadnych znaków specjalnych regex.” Jest nieprawidłowe, patrz specyfikacja (również prawdziwe dla HTML4))Odpowiedzi:
Ta
classList
właściwość nie jest obsługiwana przez IE9 i starsze. IE10 + obsługuje to jednak.Użyj
className += " .."
zamiast tego. Uwaga: nie pomijaj spacji: nazwy klas powinny być dodawane w postaci listy oddzielonej spacjami.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);
źródło
className
Atrybut istnieje zawsze. Jest inicjowany jako pusty ciąg. Aby ułatwić obsługę kodu,+=
zaleca się użycie do dodawania nazw klas.className
właściwość elementu DOM to odczyt i zapis.Jak wspomniano wcześniej,
classList
nie jest obsługiwany przez IE9 i starsze. Oprócz powyższej alternatywy Alexa, istnieje kilka polifillów, które mają na celu zastąpienie ich, tj. Po prostu umieść je na swojej stronie, a IE powinno po prostu działać (słynne ostatnie słowa!).https://github.com/eligrey/classList.js/blob/master/classList.js
https://gist.github.com/devongovett/1381839
źródło
/** * 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, ' ')); } }
źródło
ele.getAttribute('class')
w niektórych przypadkach zwracałem wartość null (może jeśli atrybut klasy nie jest jeszcze ustawiony?) - prosta instrukcja if rozwiązała problem.W IE 10 i 11 właściwość classList jest zdefiniowana w HTMLElement.prototype.
Aby to działało na elementach SVG, właściwość powinna być zdefiniowana w Element.prototype, tak jak w innych przeglądarkach.
Bardzo małą poprawką byłoby skopiowanie dokładnego propertyDescriptor z HTMLElement.prototype do 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
wyrzuciInvalid calling object
Dla IE 8 i 9 użyj następującego kodu, dołączyłem również (zminimalizowany) polyfill dla Array.prototype.indexOf, ponieważ IE 8 nie obsługuje go natywnie (źródło 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; } });
źródło
)
.Sprawdź to
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 })
i classList zadziała!
document.getElementsByTagName("div")[0].classList ["aclass"] document.getElementsByTagName("div")[0].classList.add("myclass") document.getElementsByTagName("div")[0].className "aclass myclass"
to wszystko!
źródło
W Eksploratorze 11 classList.add działa tylko z pojedynczymi wartościami.
Element.classList.add("classOne", "classTwo");
W tym przypadku Explorer dodaje tylko pierwszą klasę i ignoruje drugą. Więc musisz zrobić:
Element.classList.add("classOne"); Element.classList.add("classTwo");
źródło
classList
nie jest obsługiwany w IE <9. Użyj jQuery.addClass lub polyfill, takiego jak ten na https://developer.mozilla.org/en-US/docs/Web/API/Element/classListźródło
classList