[MCSD 70-480] Interakcja z kontrolkami UI

Ostatnio poznaliśmy między innymi nowe znaczniki używane w HTML5. Dzisiaj w kolejnej części moich zapisków z nauki do egzaminu pobawimy się trochę więcej częścią z nich, spróbujemy użyć trochę JavaScriptu, a także porysujemy trochę w przeglądarce. Cieszy mnie fakt, że pierwsza część wpisów o przygotowaniu do egzaminu 70-480 została przyjęta tak ciepło co naprawdę daje mi wiele sił do tego żeby to kontynuować. W tym poście będzie nieco więcej moich własnych przykładów ze względu na to, że rysowanie po canvasie nie jest moją mocną stroną i dobrze będzie spróbować tego samemu.

Manipulowanie DOMem

Czym jest DOM? Document Object Model to reprezentacja struktury HTML naszej strony w formie obiektów, którymi możemy manipulować. Jak tłumaczyłem w poprzednim wpisie każda strona HTML ma strukturę hierarchiczną. Oznacza to, że wszystkie elementy mają swoich rodziców i dzieci. Przeglądarka w sposób niewidzialny dla użytkownika tworzy tą strukturę w formie obiektów, które posiadają dokładnie taką samą strukturę jak struktura zawarta w znacznikach. Pozwala nam to w dowolnym momencie uzyskać dostęp do tych elementów za pomocą języka JavaScript.

Dobieranie się do obiektów

Na to żeby się dobrać do konkretnego obiektu w dzisiejszych czasach programiści mają swoje najróżniejsze sposoby. Możemy użyć framework’ów takich jak jQuery, czy zbudować stronę w oparciu o Angulara itp. Wiadomo, że nowe dzień bez nowego frameworka JSowego to dzień stracony, więc i możliwości cała masa. Jednakże pod spodem wszystko sprowadza się do czystego JS’a i manipulacji na DOMie. I na tej podstawie się dzisiaj skupimy. W zależności od tego jak nasze obiekty są zbudowane mamy kilka metod do tego, żeby się do nich odwołać:

Metoda Opis
 getElementById Zwraca jeden obiekt strony po jego unikalnym kluczu id
 getElementsByClassName Zwraca wszystkie obiekty strony po ich klasie
 getElementsByTagName  Zwraca wszystkie obiekty strony po ich znaczniku
 querySelector Zwraca pierwszy obiekt, który pasuje do wprowadzonego kryterium CSS
 querySelectorAll Zwraca wszystkie obiety, które pasują do wprowadzonego kryterium CSS

Na szczęście większość metod w JavaScriptcie jest bardzo jednoznacznych i już po samej nazwie można się domyślić co będą robiły. Jednakże w związku z tym, że chcę być dokładny posłużę się przykładem żeby je wszystkie omówić. Mamy taką oto strukturę strony:

<body>
  <div id="outerDiv">
    <p class='mainPara'>Main Paragraph</p>
    <ul>
      <li>First List Item</li>
      <li>Second List Item</li>
      <li>Third List Item</li>
      <li>Fourth List Item</li>
    </ul>
    <div id="innerDiv">
      <p class='subPara' id='P1'>Paragraph 1</p>
      <p class='subPara' id='P2'>Paragraph 2</p>
      <p class='subPara' id='P3'>Paragraph 3</p>
      <p class='subPara' id='P4'>Paragraph 4</p>
    </div>
    <table>
      <tr>
        <td>Row 1</td>
      </tr>
      <tr>
        <td>Row 2</td>
      </tr>
      <tr>
        <td>Row 3</td>
      </tr>
      <tr>
      <td>Row 4</td>
      </tr>
      <tr>
        <td>Row 5</td>
      </tr>
    </table>
    <input type="text"/><input type="submit" value="Submit"/>
  </div>
</body>
 

 getElementById

Jak wspomniane w tabelce metoda getElementById zwróci nam jeden element ze struktury, który ma unikalny klucz podany w parametrze metody.

 
var element = document.getElementById("outerDiv"); 
alert(element.innerHTML); 

Powyższy przykład pobierze do zmiennej element wszystko to co znajduje się w divie <div id=”outerDiv”> w związku z czym na ekranie zobaczymy takie okno:

Kiedy już mamy pobraną referencję do elementu outerDiv i przypisaną do zmiennej możemy z nią robić wszystko co nam się podoba. Bez problemu możemy usuwać, dodawać, zmieniać wszystkie elementy wewnątrz tego obiektu. Należy oczywiście pamiętać o tym, że w zmiennej element zapisana jest struktura DOM obiektu, także do wszystkich elementów podrzędnych mamy dostęp tak jak do właściwości normalnego obiektu.

getElementsByClassName

Kolejna metoda jest podobna do tej wyżej opisanej z tą różnicą, że pobierze nam wszystkie elementy, które mają ustawioną odpowiednią klasę. Przykładowo:

 
var paragraphs = document.getElementsByClassName("subPara"); 
alert("Mamy " + paragraphs.length + " elementów o klasie subPara"); 

Wyświetli nam ile elementów na stronie posiada klasę subPara. Tak jak w poprzednim przykładzie pobierając referencję do obiektu przechowywaliśmy obiekt DOM, tak tutaj przechowujemy listę takich obiektów w związku z czym na liście tej mamy do dyspozycji wszystkie metody, których normalnie na listach używamy.

Jedna mała uwaga. Większość z nas jest przyzwyczajona do dobierania się do elementów na stronie za pomocą jQuery. Tam składnia jest nieco prostsza. Możemy użyć np.

 
var element= $("#outerDiv"); 
var paragraphs = $(".subPara"); 

Trzeba pamiętać o tym, że w jQuery wyszukując klas wpisujemy kropkę (.) przed nazwą klasy, a wyszukując po Id wpisujemy hash (#) przed idkiem. W czystym JavaScriptcie nie używamy tych znaków ze względu na to, że mamy dwie odrębne metody.

getElementsByTagName

Ostatnia metoda z rodziny getElement* ponownie zwraca nam listę elementów. Jednakże od poprzedniej metody różni się tym, że jako parametr podajemy nazwę znacznika HTMLowego.

 
var paragraphs = document.getElementsByTagName("p"); 
alert("Mamy " + paragraphs.length + " elementów "); 

Wygląda podobnie jak poprzednio prawda? Z tą różnicą, że poprzedni przykład zwróci nam 4 elementy, a ten tutaj 5.

querySelector i querySelectorAll

Dwie ostatnie metody są bardzo podobne właśnie do tego co znamy z jQuery. Właśnie w tych metodach możemy używać kropek i hashów do wyciągania elementów o danej klasie czy idku. Jednak możliwości jest znacznie więcej. Możemy napisać napisać coś takiego:

 
document.querySelector("div &amp;gt; p");

Taki prosty kod wyciągnie nam pierwszy paragraf <p>, który znajduje się w znaczniku <div>.

Możemy zrobić też tak:

 
document.querySelectorAll("a[target]");

co znajdzie nam wszystkie elementy <a>, które posiadają atrybut target.

Możliwości jest naprawdę cała masa, a jako punkt startowy na chwilę obecną odsyłam do W3Schools querySelector oraz querySelectorAll.

Zmiana struktury DOM

Wiemy już jak się dobrać do elementów naszej strony. No i fajnie. Tylko dobrze byłoby jeszcze wiedzieć co można z nimi zrobić. A może bardzo dużo. Właściwie można zbudować całą stronę za pomocą JavaScriptu i dodawaniu kolejnych elementów do DOMu (tylko po co 🙂 ). Tak czy inaczej warto poznać kilka podstawowych metod którymi można się posłużyć do zmiany struktury naszej strony.

createElement

Za pomocą tej metody możemy oczywiście tworzyć nowe elementy. Zasada jest bardzo prosta:

 
var element = document.createElement("article");
element.innerText = "Mój nowy &amp;lt;article&amp;gt;!";

Wywołujemy metodę createElement i jako argument podajemy nazwę znacznika którego chcemy użyć. Następnie możemy już bez żadnych problemów modyfikować go jak każdy inny element DOM (np. dodając mu style, tekst, czy atrybuty).

Jednakże tworząc w taki sposób element nie pojawi on się nam magicznie na stronie. Nie zrobi tego, bo nie wie biedny gdzie ma się na tej stronie podziać. Dlatego mamy kolejne metody.

appendChild, insertBefore

Te dwie metody to tylko przykłady metod których możemy użyć do wstawiania elementów na stronę. Działają one tak:

 
var element = document.createElement("article");
element.innerText = "Mój nowy &amp;lt;article&amp;gt;";
var outerDiv = document.getElementById("outerDiv");
outerDiv.appendChild(element);

appendChild dodaje nam nasz nowy element jako ostatnie dziecko (element podrzędny) do struktury danego elementu.

 
var element = document.getElementById("outerDiv").insertBefore(
                    document.createElement("article"), 
                    document.getElementById("innerDiv"));
element.innerText = "Mój nowy &amp;lt;article&amp;gt;";

insertBefore przyjmuje dwa parametry. Ale po kolei. Tak jak w poprzednim przypadku wstawiamy element jako dziecko do struktury, jednak zamiast wrzucać na koniec to podajemy w drugim parametrze przed jakim elementem powinniśmy umieścić nasz nowy obiekt. Proste i całkiem schludne 🙂

removeChild i removeNode

Wiemy jak stworzyć, wiemy jak umieścić na stronie to pozostaje już tylko nauczyć się jak się pozbyć elementów ze strony. Tutaj sprawa jest chyba najprostsza:

 
var element = document.getElementById("innerDiv");
document.removeChild(element);

Ten kod się w zasadzie sam tłumaczy 🙂

Nieco ciekawiej jest w przypadku removeNode

 
var element = document.getElementById("innerDiv");
element.removeNode(true);

Kod trochę podobny tyle, że wywoływany bezpośrednio na obiekcie. Dodatkowo removeNode z parametrem true przeprowadza głębokie usuwanie, czyli usuwa zupełnie wszystkie dzieci danego elementu.

replaceChild i replaceNode

Te dwie metody w zasadzie działają podobnie jak removeChild removeNode z tą różnicą, że w miejsce usuwanych elementów wstawiamy nowe 🙂

Szybki kod, który wierzę, że po dzisiejszym artykule sami sobie rozszyfrujecie (oczywiście jeśli dla kogoś będzie problem to niech pisze w komentarzach):

 
var innerDiv = document.getElementById("innerDiv");
var newDiv = document.createElement("div");
for (var i = 0; i &amp;lt; innerDiv.childNodes.length; i++) 
    {
    var anchor = newDiv.appendChild(document.createElement("a"));
    anchor.setAttribute("href", "http://www.bing.ca");
    anchor.text = innerDiv.childNodes[i].textContent;
    newDiv.appendChild(document.createElement("br"));
    }
innerDiv.replaceNode(newDiv);

Uffff

To by było chyba na tyle. Oczywiście nie jest to temat zgłębiony całkowicie. JavaScript ma olbrzymie możliwości i powstają na ten temat baaardzo grube książki. To co tutaj zostało przedstawione to takie w zasadzie podstawy DOMu, które mam nadzieję, że wystarczą na egzaminie 🙂 Dawajcie znać jeśli coś z tego wszystkiego jest niejasne.

Related posts