Traduzione in corso.

Element.classList è una proprietà di sola lettura che restituisce la DOMTokenList raccolta delle classi dell'elemento.

L'utilizzo di classList è una comoda alternativa all'accesso all'elenco di classi di un elemento come stringa delimitata dallo spazio tramite element.className.

Sintassi

const elementClasses = elementNodeReference.classList;

elementClasses è un DOMTokenList che rappresenta l'attributo di classe di elementNodeReference. Se l'attributo class non è stato impostato o è vuoto elementClasses.length ritorna 0. element.classList è di sola lettura, sebbene sia possibile modificarlo utilizzando i metodi add()remove().

Metodi

add( String [, String [, ...]] )
Aggiunge classi specificate. Se queste classi esistono già, vengono ignorate.
remove( String [, String [, ...]] )
Rimuove le classi specificate.
Nota: la rimozione di una classe inesistente NON genera un errore.
item( Number )
Restituisce il valore della classe per indice in collezione.
toggle( String [, force] )
Quando è presente un solo argomento aggiunge / rimuove il valore della classe; ad esempio, se la classe esiste quando la rimuove ritorna false, altrimenti, aggiunge essa e ritorna true.
Quando è presente un secondo argomento: Se il secondo argomento restituisce true, aggiunge un valore di classe specificato rimuoverlo.
contains( String )
Verifica se esiste la classe specificata è presente nell'attributo dell'elemento.
replace( oldClass, newClass )
Sostituisce una classe esistente con una nuova classe.

Esempi

const div = document.createElement('div');
div.className = 'foo';

// il nostro stato iniziale: <div class="foo"></div>
console.log(div.outerHTML);

// usa l'API classList per rimuovere e aggiungere classi
div.classList.remove("foo");
div.classList.add("anotherclass");

// <div class="anotherclass"></div>
console.log(div.outerHTML);

// se "visibile" è impostato rimuovilo, altrimenti aggiungilo
div.classList.toggle("visible");

// aggiungi / rimuovi "visibile", a seconda del test condizionale, i meno di 10
div.classList.toggle("visible", i < 10 );

console.log(div.classList.contains("foo"));

// aggiungere o rimuovere più classi
div.classList.add("foo", "bar", "baz");
div.classList.remove("foo", "bar", "baz");

// aggiungere o rimuovere più classi utilizzando la sintassi di diffusione
const cls = ["foo", "bar"];
div.classList.add(...cls); 
div.classList.remove(...cls);

// sostituire la classe "foo" con la classe "bar"
div.classList.replace("foo", "bar");

Le versioni di Firefox precedenti alla 26 non implementano l'uso di diversi argomenti nei metodi add / remove / toggle. Vedi https://bugzilla.mozilla.org/show_bug.cgi?id=814014

Polyfill

L'evento legacy onpropertychange può essere utilizzato per creare un mockup di classList live in considerazione del fatto che esiste una proprietà Element.prototype.className che genererà questo evento quando modificato. Il seguente polyfill implementerà sia classList che la sua DOMFokenList corrispondente. Il seguente polyfill garantisce la piena conformità agli standard per tutti i metodi DOMTokenList e l'accesso a Element.prototype.classList in IE10-IE11 e in più il comportamento "abbastanza standard" (per la maggior parte delle applicazioni generali) in IE6-9.

// 1. String.prototype.trim polyfill
if (!"".trim) String.prototype.trim = function(){ return this.replace(/^[s]+|[s]+$/g, ''); };
(function(window){"use strict"; // previene l'inquinamento dello spazio dei nomi globale
function checkIfValidClassListEntry(O, V){
if (V === "") throw new DOMException(
  "Impossibile eseguire '" + O + "' su 'DOMTokenList': Il token fornito non deve essere vuoto." );
if((wsI=V.search(wsRE))!==-1)throw new DOMException("Impossibile eseguire '"+O+"' su 'DOMTokenList': "+
"Il token fornito ('"+V[wsI]+"') contiene caratteri spazio HTML, che non sono validi nei token.");
  }
// 2. Implementa il polyfill vivacità di barebone DOMTokenList
if (typeof DOMTokenList !== "function") (function(window){
    var document = window.document, Object = window.Object, hasOwnProp = Object.prototype.hasOwnProperty;
    var defineProperty = Object.defineProperty, allowTokenListConstruction = 0, skipPropChange = 0;
    var Element = window.Element, wsI = 0, wsRE = /[\11\12\14\15\40]/; // WhiteSpace Regular Expression
    function DOMTokenList(){
        if (!allowTokenListConstruction) throw TypeError("Illegal constructor"); // lasciarlo passare internamente
    }
    DOMTokenList.prototype.toString = DOMTokenList.prototype.toLocaleString = function(){return this.value};
    DOMTokenList.prototype.add = function(){
        a: for(var v=0, argLen=arguments.length,val="",ele=this["uCL"],proto=ele[" uCLp"]; v!==argLen; ++v) {
            val = arguments[v] + "", checkIfValidClassListEntry("add", val);
            for (var i=0, Len=proto.length, resStr=val; i !== Len; ++i)
                if (this[i] === val) continue a; else resStr += " " + this[i];
            this[Len] = val, proto.length += 1, proto.value = resStr;
        }
        skipPropChange = 1, ele.className = proto.value, skipPropChange = 0;
    };
    DOMTokenList.prototype.remove = function(){
        for (var v=0, argLen=arguments.length,val="",ele=this["uCL"],proto=ele[" uCLp"]; v !== argLen; ++v) {
            val = arguments[v] + "", checkIfValidClassListEntry("remove", val);
            for (var i=0, Len=proto.length, resStr="", is=0; i !== Len; ++i)
                if(is){ this[i-1]=this[i] }else{ if(this[i] !== val){ resStr+=this[i]+" "; }else{ is=1; } }
            if (!is) continue;
            delete this[Len], proto.length -= 1, proto.value = resStr;
        }
        skipPropChange = 1, ele.className = proto.value, skipPropChange = 0;
    };
    window.DOMTokenList = DOMTokenList;
    function whenPropChanges(){
        var evt = window.event, prop = evt.propertyName;
        if ( !skipPropChange && (prop==="className" || (prop==="classList" && !defineProperty)) ) {
            var target = evt.srcElement, protoObjProto = target[" uCLp"], strval = "" + target[prop];
            var tokens=strval.trim().split(wsRE), resTokenList=target[prop==="classList"?" uCL":"classList"];
            var oldLen = protoObjProto.length;
            a: for(var cI = 0, cLen = protoObjProto.length = tokens.length, sub = 0; cI !== cLen; ++cI){
                for(var innerI=0; innerI!==cI; ++innerI) if(tokens[innerI]===tokens[cI]) {sub++; continue a;}
                resTokenList[cI-sub] = tokens[cI];
            }
            for (var i=cLen-sub; i < oldLen; ++i) delete resTokenList[i]; //remove trailing indexs
            if(prop !== "classList") return;
            skipPropChange = 1, target.classList = resTokenList, target.className = strval;
            skipPropChange = 0, resTokenList.length = tokens.length - sub;
        }
    }
    function polyfillClassList(ele){
        if (!ele || !("innerHTML" in ele)) throw TypeError("Illegal invocation");
        srcEle.detachEvent( "onpropertychange", whenPropChanges ); // prevenire il loop infinito del gestore duplicato
        allowTokenListConstruction = 1;
        try{ function protoObj(){} protoObj.prototype = new DOMTokenList(); }
        finally { allowTokenListConstruction = 0 }
        var protoObjProto = protoObj.prototype, resTokenList = new protoObj();
        a: for(var toks=ele.className.trim().split(wsRE), cI=0, cLen=toks.length, sub=0; cI !== cLen; ++cI){
            for (var innerI=0; innerI !== cI; ++innerI) if (toks[innerI] === toks[cI]) { sub++; continue a; }
            this[cI-sub] = toks[cI];
        }
        protoObjProto.length = Len-sub, protoObjProto.value = ele.className, protoObjProto[" uCL"] = ele;
        if (defineProperty) { defineProperty(ele, "classList", { // IE8 e IE9 consentono defineProperty sul DOM
            enumerable:   1, get: function(){return resTokenList},
            configurable: 0, set: function(newVal){
                skipPropChange = 1, ele.className = protoObjProto.value = (newVal += ""), skipPropChange = 0;
                var toks = newVal.trim().split(wsRE), oldLen = protoObjProto.length;
                a: for(var cI = 0, cLen = protoObjProto.length = toks.length, sub = 0; cI !== cLen; ++cI){
                    for(var innerI=0; innerI!==cI; ++innerI) if(toks[innerI]===toks[cI]) {sub++; continue a;}
                    resTokenList[cI-sub] = toks[cI];
                }
                for (var i=cLen-sub; i < oldLen; ++i) delete resTokenList[i]; // rimuovere gli indici finali
            }
        }); defineProperty(ele, " uCLp", { // per accedere al prototype nascosto
            enumerable: 0, configurable: 0, writeable: 0, value: protoObj.prototype
        }); defineProperty(protoObjProto, " uCL", {
            enumerable: 0, configurable: 0, writeable: 0, value: ele
        }); } else { ele.classList=resTokenList, ele[" uCL"]=resTokenList, ele[" uCLp"]=protoObj.prototype; }
        srcEle.attachEvent( "onpropertychange", whenPropChanges );
    }
    try { // Versione molto più veloce e pulita per IE8 e IE9:
        // Dovrebbe funzionare in IE8 perché Element.prototype instanceof Node è true in base alle specifiche
        window.Object.defineProperty(window.Element.prototype, "classList", {
            enumerable: 1,   get: function(val){
                                 if (!hasOwnProp.call(ele, "classList")) polyfillClassList(this);
                                 return this.classList;
                             },
            configurable: 0, set: function(val){this.className = val}
        });
    } catch(e) { // Fallback meno performante per i browser più vecchi (IE 6-8):
        window[" uCL"] = polyfillClassList;
        // il codice sottostante assicura che polyfillClassList venga applicato a tutti gli elementi attuali e futuri nel documento.
        document.documentElement.firstChild.appendChild(document.createElement('style')).styleSheet.cssText=(
            '_*{x-uCLp:expression(!this.hasOwnProperty("classList")&&window[" uCL"](this))}' + //  IE6
            '[class]{x-uCLp/**/:expression(!this.hasOwnProperty("classList")&&window[" uCL"](this))}' //IE7-8
        );
    }
})();
// 3. Patch per i metodi non supportati in DOMTokenList
(function(DOMTokenListProto, testClass){
    if (!DOMTokenListProto.item) DOMTokenListProto.item = function(i){
        function NullCheck(n) {return n===void 0 ? null : n} return NullCheck(this[i]);
    };
    if (!DOMTokenListProto.toggle || testClass.toggle("a",0)!==false) DOMTokenListProto.toggle=function(val){
        if (arguments.length > 1) return (this[arguments[1] ? "add" : "remove"](val), !!arguments[1]);
        var oldValue = this.value;
        return (this.remove(oldToken), oldValue === this.value && (this.add(val), true) /*|| false*/);
    };
    if (!DOMTokenListProto.replace || typeof testClass.replace("a", "b") !== "boolean")
        DOMTokenListProto.replace = function(oldToken, newToken){
            checkIfValidClassListEntry("replace", oldToken), checkIfValidClassListEntry("replace", newToken);
            var oldValue = this.value;
            return (this.remove(oldToken), this.value !== oldValue && (this.add(newToken), true));
        };
    if (!DOMTokenListProto.contains) DOMTokenListProto.contains = function(value){
        for (var i=0,Len=this.length; i !== Len; ++i) if (this[i] === value) return true;
        return false;
    };
    if (!DOMTokenListProto.forEach) DOMTokenListProto.forEach = function(f){
        if (arguments.length === 1) for (var i = 0, Len = this.length; i !== Len; ++i) f( this[i], i, this);
        else for (var i=0,Len=this.length,tArg=arguments[1]; i !== Len; ++i) f.call(tArg, this[i], i, this);
    };
    if (!DOMTokenListProto.entries) DOMTokenListProto.entries = function(){
        var nextIndex = 0, that = this;
        return {next: function() {
            return nextIndex<that.length ? {value: [nextIndex, that[nextIndex]], done: false} : {done: true};
        }};
    };
    if (!DOMTokenListProto.values) DOMTokenListProto.values = function(){
        var nextIndex = 0, that = this;
        return {next: function() {
            return nextIndex<that.length ? {value: that[nextIndex], done: false} : {done: true};
        }};
    };
    if (!DOMTokenListProto.keys) DOMTokenListProto.keys = function(){
        var nextIndex = 0, that = this;
        return {next: function() {
            return nextIndex<that.length ? {value: nextIndex, done: false} : {done: true};
        }};
    };
})(window.DOMTokenList.prototype, window.document.createElement("div").classList);
})(window);

Si prega di notare che il polyfill sopra è limitato nelle sue funzionalità. Al momento non è in grado di eseguire il polyfill fuori dagli elementi del documento (ad esempio, elementi creati da document.createElement prima di essere appendChild su un nodo padre) in IE 6-7. Tuttavia, dovrebbe funzionare bene in IE9. Una notevole discrepenza tra la versione polyfilled di classList e le specifiche W3 è in IE6-8, non c'è modo di creare un oggetto immutabile (un oggetto le cui proprietà non possono essere modificate direttamente). In IE9, tuttavia, è possibile estendere il prototye, congelando l'oggetto visibile e sovrascrivendo i metodi di proprietà native. Tuttavia, tali azioni non funzionerebbero in IE6-IE8 e, in IE9, rallenterebbero le prestazioni dell'intera pagina Web in una scansione di lumache, rendendo queste modifiche completamente poco pratiche per questo polyfill. Una nota minore è che in IE6-7 questo polyfill usa la proprietà window[" uCL"] sull'oggetto window per comunicare con le espressioni CSS, la proprietà css x-uCLp su tutti gli elementi e la proprietà element[" uCL"] su tutti gli elementi per consentire la garbage collection e aumentare le prestazioni. In tutti i browser con Polyfill (IE6-9), un ulteriore  proprietà element[" uCLp"] viene aggiunta all'elemento per garantire la prototipazione conforme agli standard e alla proprietà DOMTokenList[" uCL"] viene aggiunto a ogni elemento in element["classList"] per assicurare che il DOMTokenList sia limitato al proprio elemento.

Specificazioni

Specificazione Stato Commento
DOM
The definition of 'Element.classList' in that specification.
Living Standard Initial definition
DOM4
The definition of 'Element.classList' in that specification.
Obsolete  

Compatibilità con i browser

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung Internet
Basic supportChrome Full support 8Edge Full support 16
Full support 16
Partial support 12
Notes
Notes Not supported for SVG elements.
Firefox Full support 3.6IE Full support 10Opera Full support YesSafari Full support 5.1WebView Android Full support YesChrome Android Full support YesEdge Mobile Full support 12Firefox Android Full support YesOpera Android ? Safari iOS Full support 5Samsung Internet Android ?
toggle() method's second argumentChrome Full support 24Edge Full support 12Firefox Full support 24IE No support NoOpera Full support 15Safari Full support 7WebView Android Full support YesChrome Android Full support YesEdge Mobile Full support 12Firefox Android Full support 24Opera Android ? Safari iOS Full support 7Samsung Internet Android ?
Multiple arguments for add() & remove()Chrome Full support 24Edge Full support 12Firefox Full support 26IE No support NoOpera Full support 15Safari Full support 7WebView Android Full support YesChrome Android Full support YesEdge Mobile Full support 12Firefox Android Full support 26Opera Android ? Safari iOS Full support 7Samsung Internet Android ?
replace()Chrome Full support 61Edge ? Firefox Full support 49IE No support NoOpera ? Safari No support NoWebView Android ? Chrome Android Full support 61Edge Mobile ? Firefox Android Full support 49Opera Android ? Safari iOS No support NoSamsung Internet Android ?

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.

Guarda anche

Tag del documento e collaboratori

Hanno collaborato alla realizzazione di questa pagina: IsibisiDev, LBreda
Ultima modifica di: IsibisiDev,