DOM (ang. Document Object Model)

DOM0 to pierwsza wersja DOM.

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

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 JavaScript) albo encją. Stosowany w dokumentach XHTML z parserem XML. Takie dokumenty nie będą używały DOM HTML. W przeciwieństwie do DOM HTML, wielkość liter nazwy elementu we właściwości nodeName będzie zachowana.

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. We właśćiwośći nodeName istnieje nazwa elementu podana wielkimi literami.

Podstawowe obiekty

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

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

Odnajdywanie elementów

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

Po nazwie znacznika 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

Po identyfikatorze

Uwaga na pisownię wielkich i małych liter!

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

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

Kolekcje

Kolekcji używa się tak, jak tablic:

 for (x in bary)
 bary[x]

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ć.

 function getElementsByClass(className) {
 var i, pasujace = [], odnosniki = document.getElementsByTagName('*')
 for (i in odnosniki) {
 if (odnosniki[i].className === className) pasujace[pasujace.length] = odnosniki[i];
 }
 return pasujace;
 }

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 korzystać z metody getElementsByTagName do pobrania wszystkich elementów na stronie i używać indeksów. 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

Atrybuty odczytuje się za pomocą nazwa, a ustawia za pomocą nazwa = wartość. Aby sprawdzić, czy dany atrybut istnieje, należy sprawdzić czy istnieje właśćiwość która jest nazwą atrybutu. Wszystkie atrybuty nazywają się tak samo, jak w XHTML. Wyjątkiem jest class, który w JavaScript nazywa się className, ponieważ class jest słowem kluczowym.

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

 anchor = document.getElementById('kurs');

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

 if (anchor.className) 
 { 
   var anchorClassName = anchor.className;
   alert(anchorClassName); //jeżeli istnieje atrybut class, to zwróci jego wartość
 }
 anchor.rel = "kurs"; //nadpisze rel

Do usuwania atrybutów należy używać metody removeAttribute(nazwa).

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 zawartych w nim węzłów .

  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 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(h1,document.body.childNodes[0]);

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.

Wstawianie za elementem

DOM W3C nie ma metody insertAfter, która by to robiła, napiszemy ją sami:

 Node.prototype.insertAfter = function(newNode) {
 this.parentNode.insertBefore(newNode, this.nextSibling ? this.nextSibling : null)
 }

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ą węzły albo mieć od razu stworzone odpowiednie elementy w kodzie XHTML i tylko je ukrywać i pokazywać za pomocą pseudoklas CSS.


Zmodyfikowano: 20.11.2011, 09:30
submit