JavaScript'te bir öğenin sınıflarını değiştirmenin en pratik yolu element.classList özelliğidir: add(), remove(), toggle() ve replace() metotlarıyla sınıf ekler, kaldırır ve değiştirirsiniz. Herhangi bir özniteliği okumak ve yazmak için getAttribute() ve setAttribute(), satır içi stil vermek için element.style kullanılır. Pek çok öznitelik ayrıca öğe nesnesinde aynı adlı bir özellik olarak yansıtılır.
Bu yazıda öznitelik ile özellik arasındaki farkı, MDN'in yansıtma (reflection) kurallarını, mantıksal ve numaralandırılmış öznitelikleri, DOMTokenList metotlarının hatalarını ve style nesnesinin davranışını anlatıyoruz. data-* öznitelikleri ve dataset HTML tarafıyla ilgili olduğu için HTML öğrenme rehberi serisinde ele alınıyor. Serinin tamamı için Web API öğrenme rehberi sayfasına bakabilirsiniz.
Öznitelik (attribute) ile özellik (property) farkı
Öznitelik, HTML'de etiketin içine yazdığınız ad="değer" çiftidir: <input placeholder="Ad"> içindeki placeholder gibi. DOM'da her öznitelik bir Attr düğümüyle temsil edilir ve öğenin attributes özelliğindeki NamedNodeMap içinde durur. Özellik ise JavaScript nesnesinin bir alanıdır: input.placeholder gibi. MDN, pek çok özniteliğin ilgili DOM arayüzünde yansıtıldığını (reflected) açıklar: özelliği okumak özniteliği okumak, özelliğe yazmak özniteliğe yazmak demektir ve bu ilişki iki yönlüdür.
<input placeholder="Original placeholder" />const input = document.querySelector("input");
// Genel yöntem: öznitelik metotları
let attr = input.getAttribute("placeholder");
input.setAttribute("placeholder", "Modified placeholder");
// Aynı işlem yansıtılan özellikle
attr = input.placeholder;
input.placeholder = "Modified placeholder";MDN, yansıtılan özelliklerin getAttribute()/setAttribute() çağrılarına göre daha doğal bir programlama yolu sunduğunu belirtir. Ancak özellik adı her zaman öznitelik adıyla aynı değildir. Özellikler genellikle camelCase yazılır, özellikle kısa çizgi gibi özellik adında kullanılamayan karakterler içeren çok kelimeli adlarda: aria-checked özniteliği ariaChecked özelliğiyle yansıtılır. İki özel öznitelik de kendi adlarıyla değil, ayrı özelliklerle temsil edilir: id özniteliği id özelliğiyle, class özniteliği ise className özelliğiyle. MDN, class adının birçok dilde anahtar kelime olduğu için bu ismin seçildiğini not eder.
Mantıksal ve numaralandırılmış öznitelikler
Mantıksal (boolean) öznitelikler değer gerektirmez; varlıkları true, yoklukları false anlamına gelir. <input type="checkbox" checked> gibi. MDN'e göre bu kutu işaretliyken getAttribute("checked") "", işaretli değilken null döndürür; yansıtılan checked özelliği ise doğrudan true veya false verir. Mantıksal bir özniteliği setAttribute() ile açarken değerin ne olduğu önemli değildir; geleneksel olarak boş dize veya özniteliğin kendi adı verilir. Kapatmak için ise mutlaka removeAttribute() çağırmanız gerekir.
Numaralandırılmış (enumerated) öznitelikler önceden tanımlı sınırlı bir değer kümesi alır. Genel dir özniteliğinin geçerli değerleri ltr, rtl ve auto'dur ve bu değerler büyük-küçük harfe duyarsızdır. MDN'e göre yansıtılan dir özelliği her zaman belirtimde tanımlı standart (canonical) biçimi döndürür; yazarken de değeri bu biçime çevirir. getAttribute() ise HTML'deki değeri olduğu gibi verir:
<p dir="RTL">Right to left</p>const pElement = document.querySelector("p");
console.log(pElement.dir); // "rtl"
console.log(pElement.getAttribute("dir")); // "RTL"getAttribute, setAttribute ve removeAttribute

element.getAttribute(name) özniteliğin dize değerini döndürür; öğede o ad yoksa null döner. HTML belgesindeki bir HTML öğesinde ad küçük harfe normalleştirilir. MDN'in örneğinde <div id="div1"> için getAttribute("id") "div1", olmayan lang için null döner. MDN iki önemli ayrıntı ekler:
- Kaynaktaki karakter referansları ayrıştırma sırasında çözülür.
data-payload="<b>hi</b>"özniteliği içingetAttribute()"<b>hi</b>"döndürür. Bu değeri zaten kaçırılmış sanıpinnerHTML'e vermek XSS'e yol açabilir. - Güvenlik nedeniyle betik dışı kaynaklardan CSP nonce değerleri gizlenir;
script.getAttribute("nonce")boş dize döndürür. Nonce değeri içinscript.nonceözelliği kullanılır.
element.setAttribute(name, value) özniteliğin değerini ayarlar; öznitelik varsa günceller, yoksa ekler. HTML öğelerinde ad otomatik olarak küçük harfe çevrilir; dize olmayan değerler dizeye dönüştürülür. Ad geçersiz karakterler içeriyorsa (boşluk, /, =, > gibi) InvalidCharacterError fırlatılır. element.removeAttribute(name) özniteliği kaldırır; öznitelik yoksa hata vermeden döner. MDN, özniteliği kaldırmak için değeri null yapmak yerine bu metodu kullanmanızı önerir, çünkü pek çok öznitelik null değeriyle beklendiği gibi davranmaz.
Diğer yardımcı metotlar şunlardır: hasAttribute(name) özniteliğin varlığını true/false olarak bildirir; hasAttributes() öğede herhangi bir öznitelik olup olmadığını söyler; getAttributeNames() tüm öznitelik adlarını bir dizi olarak döndürür. MDN, getAttributeNames() ile getAttribute()'u birlikte kullanmanın attributes'a erişmeye göre bellek açısından verimli ve performanslı bir alternatif olduğunu belirtir:
for (const name of element.getAttributeNames()) {
const value = element.getAttribute(name);
console.log(name, value);
}toggleAttribute(name, force), mantıksal öznitelikler için kısa yoldur: ikinci parametre yoksa özniteliği varsa kaldırır, yoksa ekler. force true ise yalnızca ekler, false ise yalnızca kaldırır. Metot, işlem sonunda öznitelik varsa true, yoksa false döndürür.
<input value="text" /> <button>toggleAttribute("disabled")</button>const button = document.querySelector("button");
const input = document.querySelector("input");
button.addEventListener("click", () => {
input.toggleAttribute("disabled");
});setAttribute bir enjeksiyon noktası olabilir
MDN, setAttribute()'ın da bir enjeksiyon noktası (injection sink) olabileceği konusunda uyarır: bazı özniteliklerin değeri HTML, betik veya betik URL'si olarak yorumlanır. MDN'in örneğinde kullanıcıdan gelen "alert(1)" dizesi button.setAttribute("onclick", ...) ile atandığında düğmeye basılınca çalışır. Aynı risk <iframe>'in srcdoc özniteliği ve betiklerin src veya href öznitelikleri için de geçerlidir. Trusted Types zorunlu tutulduğunda bu özniteliklere düz dize yerine TrustedScript, TrustedHTML veya TrustedScriptURL nesnesi vermeniz gerekir; aksi halde TypeError alırsınız. Kullanıcı verisini olay işleyici özniteliklerine asla yazmayın; olaylar için addEventListener kullanın. Genel XSS savunması için XSS ve CSP koruma yazısına bakabilirsiniz.
classList ve DOMTokenList metotları

element.classList, öğenin class özniteliğini temsil eden canlı bir DOMTokenList döndürür. className ile sınıfları boşlukla ayrılmış tek bir dize olarak yönetmek yerine, tek tek sınıf eklemek ve kaldırmak için uygun bir alternatiftir. class özniteliği yoksa veya boşsa length değeri 0 olan boş bir liste döner.
| Metot veya özellik | Ne yapar | Dönüş değeri |
|---|---|---|
| add(t1, t2, ...) | Verilen sınıfları ekler, var olanları atlar | yok |
| remove(t1, t2, ...) | Verilen sınıfları kaldırır, olmayan sınıfta hata vermez | undefined |
| toggle(token) | Sınıf varsa kaldırır, yoksa ekler | işlem sonrası sınıf var mı (boolean) |
| toggle(token, force) | force true ise yalnızca ekler, false ise yalnızca kaldırır | boolean |
| replace(eski, yeni) | Bir sınıfı başkasıyla değiştirir | başarılıysa true, eski sınıf yoksa false |
| contains(token) | Sınıfın listede olup olmadığını test eder | boolean |
| item(i) | İndeksteki sınıfı verir | dize veya aralık dışında null |
| value | Listenin boşlukla ayrılmış dize hali | dize |
| length | Sınıf sayısı | sayı |
const div = document.createElement("div");
div.classList = "foo"; // classList.value özelliğine aktarılır
// başlangıç: <div class="foo"></div>
div.classList.remove("foo");
div.classList.add("another-class");
// <div class="another-class"></div>
div.classList.toggle("visible"); // varsa kaldır, yoksa ekle
div.classList.toggle("visible", i < 10); // koşula göre ekle veya kaldır
console.log(div.classList.contains("foo")); // false
const cls = ["foo", "bar"];
div.classList.add(...cls); // yayma sözdizimiyle birden fazla sınıf
div.classList.remove(...cls);
div.classList.replace("foo", "bar");MDN, DOMTokenList ile ilgili birkaç kuralı belirtir:
- Liste her zaman büyük-küçük harfe duyarlıdır:
Aktifileaktiffarklı sınıflardır. - Listeyi değiştiren metotlar fazla boşlukları otomatik kırpar ve yinelenen değerleri kaldırır.
class=" d d e f"olan bir öğeyeadd("x")yaptıktan sonra listed e f xolur. add()boş dizeyle çağrılırsaSyntaxError, boşluk içeren bir değerle çağrılırsaInvalidCharacterErrorfırlatır. Bu yüzdenadd("btn btn-primary")yerineadd("btn", "btn-primary")yazmalısınız.classListsalt okunurdur ama ona doğrudan bir dize atayabilirsiniz; bu,valueözelliğine atamakla eşdeğerdir.replace(), ilk sınıf listede yoksa yeni sınıfı eklemeden hemenfalsedöndürür.
toggle()'ın dönüş değeri arayüz durumunu senkron tutmak için kullanışlıdır. MDN'in örneğinde bir öğeye tıklandığında classes.toggle("c") sonucu okunur ve sınıfın eklenip eklenmediği metin olarak yazılır. force parametresi ise koşula bağlı sınıflar için idealdir; MDN örneğindeki span.classList.toggle("c", window.innerWidth > 1000) sınıfı yalnızca pencere 1000 pikselden genişse ekler. DOMTokenList yalnızca classList için değil, <link> öğesinin relList'i veya <iframe>'in sandbox'ı gibi başka öznitelikler için de kullanılır; supports() metodu bu özniteliklerde bir değerin desteklenip desteklenmediğini algılamaya yarar.
className mi classList mi?
className, class özniteliğini tek bir dize olarak yansıtır. Atama yaptığınızda tüm sınıflar değişir: el.className = "active" öğedeki diğer sınıfları siler. Tek bir sınıfı değiştirmek istediğinizde classList bu yan etkiden korur. MDN, SVG öğelerinde className'in bir SVGAnimatedString olabileceğini ve bu yüzden SVG'de sınıfı getAttribute("class")/setAttribute("class", ...) ile yönetmenin daha kolay olduğunu belirtir; boş bir class özniteliğinde getAttribute()'ın "" yerine null döndürebileceğini de not eder.
style ile satır içi stil vermek

element.style, öğenin satır içi style özniteliğini canlı bir CSSStyleProperties nesnesi olarak döndürür (MDN, eski belirtimlerin CSSStyleDeclaration döndürdüğünü not eder). Bu nesne üzerinden satır içi stilleri okuyabilir ve yazabilirsiniz:
const el = document.getElementById("kutu");
el.style.backgroundColor = "red"; // camelCase özellik adı
el.style.setProperty("border-top", "1px solid black"); // kısa çizgili ad
console.log(el.style.getPropertyValue("border-top"));
el.style.color = null; // tek bir bildirimi sıfırlar
el.style.removeProperty("border-top");MDN'in açıkladığı davranışlar şunlardır:
- Nesne, tarayıcının desteklediği tüm CSS özellikleri için hem kısa çizgili hem camelCase adlı özellikler içerir; satır içi bir değeri olmayanlar
""döner. Yaniel.style.coloryalnızcastyleözniteliğinde yazılmış rengi verir, CSS dosyasından gelen rengi vermez. - Kısa yazım (shorthand) özellikler uzun hallerine genişletilir.
border-top: 1px solid blackstiliborderTopColor,borderTopStyleveborderTopWidtholarak da okunabilir. - Bir bildirimi sıfırlamak için değeri
nullveya boş dize yapmanız yeterlidir. styleözelliği salt okunurdur, ama ona bir dize atamakcssTextözelliğine atamakla eşdeğerdir ve tüm satır içi stilleri değiştirir.styleile verilen değerler, CSS basamaklamasındastyleözniteliğiyle yazılmış satır içi bildirimle aynı önceliğe sahiptir.
Öğe referansı tutan öznitelikler
MDN'in yansıtma rehberi, değer olarak başka öğelerin kimliklerini alan öznitelikleri ayrıca ele alır. aria-labelledby="label_1 label_2 label_3" özniteliği ariaLabelledByElements özelliğiyle yansıtılır; bu özellik dizedeki kimliklere karşılık gelen öğelerden oluşan bir dizi döndürür. Kimliği eşleşen öğe yoksa (örneğin label_3 belgede yoksa) dizide yer almaz. Normal yansıtmadan farklı olarak, özelliğe bir dizi atamak özniteliği temizler ve getAttribute() artık "" döndürür; setAttribute() ile özniteliği yeniden yazmak ilişkiyi geri getirir. Özellik dizisi statiktir; dönen diziyi değiştirmek özniteliği güncellemez. Bu özellikler için tarayıcı desteğini MDN uyumluluk tablosundan kontrol edin.
Mini örnek: sekme düğmelerini yönetmek
Aşağıdaki örnek classList, mantıksal öznitelik ve aria-selected özniteliğini birlikte kullanır:
<div id="sekmeler">
<button class="sekme aktif" aria-selected="true" data-panel="p1">Genel</button>
<button class="sekme" aria-selected="false" data-panel="p2">Ayarlar</button>
</div>
<section id="p1">Genel panel</section>
<section id="p2" hidden>Ayarlar paneli</section>const sekmeler = document.querySelectorAll("#sekmeler .sekme");
for (const sekme of sekmeler) {
sekme.addEventListener("click", () => {
for (const diger of sekmeler) {
const secili = diger === sekme;
diger.classList.toggle("aktif", secili);
diger.setAttribute("aria-selected", String(secili));
const panel = document.getElementById(diger.getAttribute("data-panel"));
panel.toggleAttribute("hidden", !secili);
}
});
}toggle() ve toggleAttribute() metotlarının ikinci parametresi, koşul doğruysa ekle, yanlışsa kaldır anlamına geldiği için ayrı if dallarına gerek kalmaz. aria-selected mantıksal bir öznitelik değil, "true"/"false" dize değeri alan bir ARIA özniteliği olduğu için setAttribute() ile açıkça yazılır. Olay dinleyicisini her düğmeye ayrı eklemek yerine kapsayıcıya tek dinleyici koymak için olay delegasyonu yazısına bakabilirsiniz.
Sık yapılan hatalar
- Mantıksal özniteliği "false" ile kapatmaya çalışmak: Öznitelik var olduğu sürece
truesayılır;removeAttribute()kullanın. - className ile tek sınıf eklemek:
el.className = "yeni"diğer sınıfları siler;classList.add()kullanın. - Boşluk içeren sınıf adı vermek:
classList.add("a b")InvalidCharacterErrorfırlatır; sınıfları ayrı argüman olarak geçin. - style ile CSS dosyasındaki değeri okumaya çalışmak:
styleyalnızca satır içi stilleri gösterir. - Özellik ile öznitelik değerlerinin hep aynı olduğunu sanmak: Numaralandırılmış özniteliklerde özellik standart biçimi,
getAttribute()ham değeri verir. - Kullanıcı verisini onclick veya srcdoc gibi özniteliklere yazmak: Bu öznitelikler kod veya HTML olarak çalışır.
Sık Sorulan Sorular
setAttribute mı yoksa doğrudan özellik ataması mı kullanmalıyım?
Öznitelik yansıtılıyorsa MDN özellik kullanımını daha doğal bulur: input.placeholder = "...". Yansıtılmayan öznitelikler, ARIA veya özel öznitelikler ve SVG öğeleri için setAttribute() daha genel bir yoldur.
classList.toggle neden bazen beklediğimden farklı çalışıyor?
Tek parametreli toggle() mevcut duruma göre davranır; durumu bilmediğiniz yerlerde ikinci force parametresini vererek sonucu belirleyin. Metodun dönüş değeri, işlem sonunda sınıfın listede olup olmadığını söyler.
data- öznitelikleri nasıl okunur?
getAttribute("data-panel") her zaman çalışır. dataset özelliği ve data-* özniteliklerinin HTML tarafındaki kuralları HTML öğrenme rehberi serisinde anlatılıyor.
getAttribute ile özelliğin döndürdüğü değer neden farklı?
getAttribute() HTML'deki ham dize değerini verir. Yansıtılan özellik ise değeri türüne göre yorumlar: mantıksal özniteliklerde true/false, numaralandırılmış özniteliklerde standart küçük harf biçim döner. MDN'in dir="RTL" örneğinde özellik "rtl", getAttribute() "RTL" verir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Web API öğrenme rehberi · innerHTML ve textContent · öğe seçme · DOM öğe oluşturma · HTML öğrenme rehberi