DOM (ang. Document Object Model)

Metody DOM są dostępne nie tylko w JavaScript. Tak samo można operować na dokumentach m.in. w Javie i PHP5.

DOM to sposób przedstawienia dokumentu. Jest to zestaw metod i pól, które umożliwiają odnajdywanie, zmienianie, usuwanie i dodawanie elementów.

DOM W3C jest podzielony na dwie części. Pierwsza, podstawowa (ang. core) to ogólny sposób reprezentowania dokumentów XML. Przedstawia dokument jako drzewo zawierające węzły (ang. node). Każdy węzeł może być elementem, fragmentem tekstu, komentarzem, instrukcją preprocesora (np. dołączonym fragmentem PHP) albo encją.

Drugą częścią DOM W3C jest typowy dla przeglądarek DOM HTML. Jest to zestaw metod ułatwiających tworzenie dynamicznych stron oraz zapewniających kompatybilność wstecz z wcześniejszym prostym DOM Netscape. DOM HTML przedstawia dokument jako kilka kolekcji obiektów określonych typów (np. formularze, obrazki) oraz dodaje pola/metody ułatwiające dostęp do funkcjonalności specyficznej dla HTML, jak np. odczyt pól formularza.

Podstawowe obiekty

Głównym, globalnym obiektem w DOM przeglądarki jest window. W tym obiekcie przechowywane są wszystkie globalne zmienne i funkcje. W nim jest także obiekt document, który preprezentuje całą stronę XHTML.

document.documentElement to jest główny element dokumentu (korzeń), czyli <html>. document.body to obiekt reprezentujący <body> dokumentu.

Odnajdywanie elementów

Podstawowe metody DOM W3C można wywołać na dowolnym elemencie dokumentu lub na samym obiekcie document.

Po identyfikatorze

Uwaga na pisownię wielkich i małych liter!

Jeśli element ma identyfikator, to można go znaleźć za pomocą getElementById(id)

  var foo = document.getElementById('foo')
  if (!foo) alert('nie ma foo!')

Po nazwie elementu

getElementsByTagName(nazwa) zwraca kolekcję wszystkich elementów, które mają określoną nazwę. Jeśli poda się * zamiast nazwy, to zwróci wszystkie elementy. Zauważ, że możesz wywołać tę metodę na dowolnym elemencie i wtedy poda tylko elementy zawarte w nim:

  var bary = foo.getElementsByTagName('bar')
  bary będzie kolekcją (tablicą) wszystkich elementów o nazwie bar wewnątrz elementu reprezentowanego przez obiekt foo

Kolekcje

Kolekcje używa się tak, jak tablice:

 for(i=0;i<bary.length;i++)
 bary[i]

Kolekcje są „żywe” i reagują na zmiany w dokumencie. Przy ich używaniu trzeba mieć na uwadze, że jeśli element zostanie usunięty z dokumentu, to zniknie także ze wszystkich kolekcji.

Wg określonej klasy

DOM W3C nie ma metody do wyszukiwania elementów wg klasy, ale można łatwo taką metodę napisać.

 var i,odnosniki = document.getElementsByTagName('a')
 for(i=0;i<odnosniki.length;i++)
 if (odnosniki[i].className.match(/(^|\s)popup(\s|$)/)) znaleziono(odnosniki[i])

Fragment /(^|\s)nazwaklasy(\s|$)/ to wyrażenie regularne, które uwzględnia, że element może mieć kilka klas oddzielonych spacjami.

Powyższy kod najpierw pobierze wszystkie elementy o nazwie „a”, sprawdzi klasę (className) każdego z nich i wykona funkcję znaleziono na tych, które mają klasę „popup”.

Skakanie po węzłach (elementach)

Riddle jezeli to czytasz, mółgbys dać ilustracje z bloga do tego, jeżeli nie sprawia Ci to problemu :)

Nie potrzeba dawać identyfikatorów dla wszystkich elementów w dokumencie. Każdy węzeł (czyli element, fragment tekstu, komentarz), posiada pola wskazujące na jego sąsiednie węzły:

Nazwa pola Element
firstChild Pierwszy węzeł zawarty w tym elemencie
lastChild Ostatni węzeł w tym elemencie
previousSibling Sąsiedni węzeł przed tym elementem
nextSibling Węzeł za tym elementem
parentNode Element w którym zawarty jest ten element
childNodes Kolekcja wszystkich węzłów zawartych w tym elemencie

Pola mogą mieć wartość null, gdy nie ma węzła, który by mogły wskazywać.

Wyszukiwanie tylko elementów Bug w IE

Domyślnie ww. pola wskazują na dowolne węzły, łącznie z tekstem i komentarzami w dokumencie. Elementy od innych węzłów można odróżnić za pomocą pola nodeType.

  if (element.nextSibling && element.nextSibling.nodeType == 1)
    alert('sąsiedni węzeł jest elementem')

Kilka najczęściej spotykanych typów węzłów:

Stała Wartość Co oznacza
ELEMENT_NODE 1 Element
TEXT_NODE 3 Tekst
ENTITY_NODE 6 Encja
COMMENT_NODE 8 Komentarz (przeglądarka ma prawo ignorować komentarze)

Atrybuty Bug w IE

Atrybuty odczytuje się za pomocą getAttribute(nazwa), a ustawia za pomocą setAttribute(nazwa,wartość). Aby sprawdzić czy dany atrybut istnieje należy użyć metody hasAttribute(nazwa)

 <a href="http://kurs.browsehappy.pl/" rel="archive" id="kurs">Kurs BrowseHappy</a>

 anchor = document.getElementById('kurs');

 var anchorRel = anchor.getAttribute('rel');
 alert(anchorRel); //zwróci wartość atrybutu rel

 if(anchor.hasAttribute('class')) 
 { 
   var anchorClassName = anchor.getAttribute('class');
   alert(anchorClassName); //jeżeli istenieje atrybut class, to zwróci jego wartość
 }
 anchor.setAttribute("rel", "kurs"); //nadpisze rel
 anchor.setAttribute("lang", "pl"); //stworzy nowy atrybut i przypisze mu wartość

Mimo, że getAttribute zwraca null jeżeli atrybut nie istnieje, do usuwania atrybutów należy używać metody removeAttribute(nazwa), a nie setAttribute(nazwa, null).

Nieliczne atrybuty lepiej ustawiać za pośrednictwem specjalnych pól, które udostępniają przeglądarki. W szczególności styleclass oraz value.
W pozostałych przypadkach, nawet jeśli atrybuty są dostępne na różne sposoby, to należy używać ich za pomocą getAttribute/setAttribute.

Usuwanie elementów

Jeśli potrzebujesz usunąć element tylko na moment, możesz go ukryć

Każdy element posiada metodę removeChild pozwalającą usunąć jeden z węzłów zawarty w nim.

  element.parentNode.removeChild(element)
  element sam się usunie

Element usunięty z dokumentu nie jest całkowicie niszczony i może zostać ponownie dołączony do dokumentu.

Tworzenie, dodawanie i przenoszenie elementów

Elementy formularza mają czasem swoje własne, prostsze metody.

Elementy tworzy się przez document.createElement(nazwa). Stworzony element nie jest połączony z dokumentem. Trzeba go dodać za pomocą appendChild lub insertBefore.

  var p = document.createElement('p');
  document.body.appendChild(p);

  var h1 = document.createElement('h1');
  document.body.insertBefore(p,document.body.firstChild);

appendChild() element podany jako argument dołącza jako dziecko na koniec elementu, z którego została wywołana.

insertBefore przyjmuje dwa argumenty — element do wstawienia oraz element przed, którym ma wstawić nowy. Jeśli jako drugi argument poda się null, to zadziała tak samo jak appendChild.

Wykonanie appendChild lub insertBefore na elementach, które są już w dokumencie przeniesie je w nowe miejsce.

Tekst tworzy się za pomocą document.createTextNode("tekst") i podobnie jak elementy trzeba go wstawić do dokumentu, żeby stał się widoczny.

Tworzenie większych fragmentów dokumentu za pomocą metod DOM wymaga napisania sporo kodu, dlatego warto napisać sobie funkcje które od razu tworzą i dodają wezły albo mieć od razu stworzone odpowiednie elementy w kodzie XHTML i tylko je ukrywać i pokazywać za pomocą DHTML.


Zmodyfikowano: 25.07.2007, 19:51