DOM (Document Object Model) Nedir?

DOM (Belge Nesne Modeli), HTML, XHTML, XML gibi belgelerin script dilleriyle iletişim kurabilmesini sağlamak için geliştirilmiş bir arabirimdir ve W3C standardıdır1.

AA

W3C, DOM tanımını şu şekilde yapmaktadır: “W3C Document Object Model (DOM), programların ve komut dosyalarının bir belgenin içeriğine, yapısına ve stiline dinamik olarak erişmesini ve güncellemesini sağlayan bir platform ve dilden bağımsız bir arayüzdür.

DOM (Document Object Model)

Programlama dilleriyle ilgili pek çok içerik ve anlatımda karşımıza çıkan Object-Oriented (Nesne Yönelimli) yaklaşımı da bu yapıya benzerdir. Bu anlamda, internet tarayıcıları vasıtasıyla görüntülediğimiz internet sayfalarını belge, bu belgelerde (sayfalarda) yer alan tüm elemanları (etiket/tag) da nesne olarak nitelendirebiliriz. Buna göre resim, yazı, form gibi tüm elemanlar nesnedir.

DOM sayesinde, örneğin bir JavaScript kodu vasıtasıyla sayfa içindeki herhangi bir nesnenin özelliğine müdahale edebilir, bu özellikleri okuyabilir ve aktarabiliriz. Aşağıdaki örnek koda baktığımızda head etiketleri arasında bir CSS ve bir de JS (JavaScript) kodu görmekteyiz. CSS kodu body etiketi arasında yer alan div ile ilişkili olarak ilgili etikete bir stil (border:1px solid #ddd; margin: 20px; padding: 20px;) atamaktadır. JS kodu ise, ID değeri üzerinden (document.getElementById) yakalamakta ve mouse hareketlerine göre (onmouseover ve onclick) fonksiyon aracılığıyla (changeColor()) CSS ile atanan stil yerine kendi içeriğinde tanımlanan stil özelliklerini div etiketine uygulamaktadır.

<!DOCTYPE html>
<html>
<head>
 <title></title>
 <style type="text/css">
  div { border:1px solid #ddd; margin: 20px; padding: 20px; }
 </style>
 <script type="text/javascript">
  function changeColor(Obj){
   document.getElementById("content").style.border = '1px solid red';
   if (Obj) {
    document.getElementById("content").style.border = '1px solid green';
   } else {
    document.getElementById("content").style.border = '1px solid blue';
   }
  }
// ya da
  let changeColor = Obj => {
    let content = document.getElementById("content");
    content.style.border = '1px solid red';
    if (Obj) content.style.border = '1px solid green';
    else content.style.border = '1px solid blue';
  }
 </script>
</head>
<body>
<div id="content" onmouseover="changeColor()" onclick="changeColor('reset')">DOM Örneği</div>
</body>
</html>

Örnek uygulamada div etiketinin mouse hareketlerinden sonra CSS ile atanan özelliklere dönmediğini görebilirsiniz. Peki, neden hiç red olarak belirtilen satır uygulanmadı? Aslında, onmouseover durumunda changeColor() fonksiyonu ilk olarak bu stil değerini uygulamakta. Ancak, hemen ardından gelen if...else... içeriğinde yer alan else tanımı (Obj içeriği tanımlı olmadığı için) bu stil yerine kendi içeriğini aktarmaktadır. onclick işleminde ise Obj tanımlı (reset) olduğu için tekrar stil değerleri değişecektir.

Yukarıdaki örnekte body etiketleri arasındaki bir div etiketine müdahale etmiştik. div içeriğinde de farklı etiketleri iç içe kullandığımızda hiyerarşik (a tree of objects) bir düzen oluşturmuş oluruz ve müdahaleler için bu hiyerarşik düzeni takip ederiz. ID dışında name, class gibi (attribute) parametreler aracılığıyla da DOM nesneleriyle iletişim kurulabilir. Bu parametreler sayesinde ilgili elemente (benzeriz bir elemente ya da bir grup elemente) kolaylıkla erişir (bulur) ve işlem gerçekleştirebiliriz. Önerilen yöntem, istisnai durumlar dışında etiket ve class’lar aracılığıyla bulmadır. Peki, bulunan bir element ile ilgili (örneğin HTML dosyasında) neler yapılabilir?

  • Sayfadaki tüm HTML öğeleri değiştirilebilir,
  • Sayfadaki tüm HTML öğelerinin nitelikleri değiştirilebilir,
  • Sayfadaki tüm CSS stilleri değiştirilebilir,
  • Sayfadaki tüm HTML öğeleri ve öğelerin nitelikleri kaldırılabilir,
  • Sayfaya yeni HTML öğeleri eklenebilir,
  • Sayfadaki tüm HTML öğelerine yeni özellikler eklenebilir,
  • Sayfadaki mevcut tüm HTML etkinlikleriyle (events) ilişki kurulabilir,
  • Sayfada yeni HTML etkinlikleri (events) oluşturulabilir.

Unutmadan, internet tarayıcılarının performans kriterlerine istinaden yapılan paylaşımlarda DOM tree derinliğinin 32 elementten az olması ve 60’dan fazla ana veya iç element barındırmaması önerilmektedir2. Çünkü, kompleks bir DOM yoğun bir memory kullanımına ihtiyaç duymaktadır.

DOM Değişiklikleri ve Virtual DOM

DOM hiyerarşisi içerisinde, bir elemente müdahale etmek (örneğin CSS class’ını değiştirmek) kimi durumda bütün DOM ağacının tekrar üzerinden geçilmesine neden olabilmektedir3. Bu gibi durumlara istinaden üretilen çözümlerden biri Virtual DOM olarak ifade edilmektedir. React ve VueJS bağlamında sıklıkla değinilen Virtual DOM’un işlevini yapılandırılmış olan DOM yapısını sanal olarak kopyalamak ve işlemlerin bu sanal kopya üzerinden gerçekleştirilerek sadece farklılıkları gerçek DOM yapısına minimum sayıda işlemle aktarmak4 olarak özetleyebiliriz. Unutmadan, Virtual DOM üzerindeki değişiklikler hemen gerçek DOM’a aktarılmamaktadır. React5 ve VueJS DOM aktarımı öncesinde, Virtual DOM içerisindeki bütün değişikliklerin tamamlandığından emin olmak için bir süre beklemektedir.