Jumat, 23 September 2011

Javascript 3 (DOM dan AJAX)

Sudah pernahkah kamu mendengar istilah DOM (Document Object Model) dan AJAX (Asynchronous JavaScript and XML)? Jika belum, kamu bisa membaca terus tulisan ini dan jika sudah kamu juga bisa terus membaca tulisan ini :). Sebaiknya kamu membaca dulu tulisan bagian 1 (Pengetahuan Dasar) dan 2 (Konsep OOP) agar kamu punya sedikit gambaran Javascript yang ada dalam pembahasan kali ini.

        a. DOM (Document Object Model)
       
Ketika browser yang mendukung CSS membaca dokumen HTML yang kamu buat, mereka akan menganalisa strukturnya dan membuat sebuah titik-titik struktur (nodes), yang dapat kamu bayangkan sebagai potongan kecil informasi yang mendeskripsikan dokumenmu. Setiap node berasal dari setiap tag HTML yang kamu tulis dan akan menjadi sebuah object yang saling berhubungan dengan node lain. Sebagai ilustrasi saya berikan kode HTML berikut:

<body>
<p>
   Teks awal
   <img src="gambar.jpg">
   <em>Teks lagi</em>
</p>
</body>

Jika kamu pernah belajar struktur data, terdapat salah satu struktur data yang dikenalkan yaitu TREE. Nah, struktur dari kode HTML diatas mirip dengan tree. Diawali dengan "body" yang memiliki child node "p" dan "p" memiliki tiga child node yaitu "#text" (berisi "Teks awal"), "img" dan child terakhir adalah "em" yang memiliki satu child "#text" berisi teks "Teks lagi". Dari dokumen diatas dapat diambil beberapa pernyataan seperti berikut:

1. parentNode dari "p" adalah "body"
2. firstChild dari "p" adalah "#text" dan lastChild nya adalah "em"
3. "p" berarti juga memiliki array childNodes
4. "img" memiliki previousSibling (saudara) "#text" dan memiliki nextSibling yaitu "em"
5. karena "#text" tidak memiliki node disebelumnya dan tidak memiliki elemen lagi didalamnya maka previousSibling dan firstChild nya memiliki nilai null

Pada umumnya nama node berasal dari nama tag tapi menggunakan huruf kecil (lowercase). Kata-kata parentNode, firstChild, lastChild dan sebagainya akan sering kamu temui dalam DOM. Tapi kamu jangan merasa diintimidasi dulu dengan kata-kata yang mungkin asing dan terkesan ribet bagimu karena nanti kalau sudah terbiasa maka istilah tersebut akan kamu ingat diluar kepala. Jika kamu menggunakan jQuery, akan ada perbedaan istilah yang mungkin akan mempermudah dirimu untuk mengingatnya, misalkan "parentNode" akan diganti dengan kata "parent" saja atau childNodes akan diganti dengan "child".

        b. CARA MENDAPATKAN ELEMEN MENJADI NODE
       
Javascript memiliki beberapa method yang dapat digunakan untuk mendapatkan sebuah object dalam dokumen yang kita buat untuk melakukan analisa struktur dokumen HTML. Untuk mendapatkan object dari node-node tersebut ada tiga method yang umum digunakan dan semuanya ada di class "document" yaitu:

1. document.getElementById
2. document.getElementsByName
3. document.getElementsByTagName

Biasanya saya sering menggunakan method yang pertama dan ketiga saja sedangkan method yang kedua hampir tidak pernah saya gunakan. Method pertama yaitu "getElementById" akan mencari node dengan nama ID yang dijadikan parameter dalam fungsi ini (contoh: <div id="blok">, berarti elemen div dengan id "blok"). Dalam satu dokumen tidak boleh ada node yang memiliki nama id yang sama karena itu method ini menggunakan kata "getElement" dan bukan "getElements". Contoh penggunaannya:

var blok = document.getElementById('blok');
if (blok == null) { alert('node tidak ketemu!'); }

Pada kode diatas, jika elemen dengan id "blok" ditemukan kita dapat melakukan bermacam operasi pada object blok. Sedangkan method getElementByName dan getElementByTagName sesuai dengan namanya kamu pasti sudah tahu kegunaannya. Dua method ini biasanya akan mengembalikan hasil berupa array dari object. Misalkan di dokumen kita ada beberapa tag paragraf (p) tapi kita ingin melakukan operasi pada paragraf yang pertama saja maka kita dapat menggunakan cara seperti berikut:

var paragraf = document.getElementsByTagName('p')[0];
paragraf.className = 'pertama';

Kode diatas memberikan nama class "pertama" pada paragraf pertama dalam dokumen. Karena method getElementsByTagName mereturn array maka kita langsung dapat mengakses elemen pertama dari array tersebut menggunakan tanda "[0]" setelah pemanggilan method getElementsByTagName seperti pada contoh diatas.

    c. DOM ready
   
Jika kamu membuat kode dengan DOM yang dijalankan saat browser meload halaman (otomatis dijalankan saat halaman muncul) maka kamu harus memastikan bahwa semua elemen sudah dirender oleh browser agar tidak menghasilkan nilai NULL. Pada umumnya kita membuat kode Javascript di dalam bagian HEAD yang dieksekusi oleh browser sebelum masuk ke bagian BODY. Jika bagian BODY belum dirender oleh browser maka kodemu di HEAD akan gagal karena node-node nya belum ada. Nah agar kodemu dijalankan setelah browser selesai merender semua elemen kamu bisa menggunakan event "onload" di class "window" seperti contoh berikut:

<html>
<head>
<title>DOM ready</title>
<script type="text/javascript">
window.onload = function(e) {
    var p = document.getElementsByTagName('p');
    alert(p[0].innerHTML);
}
</script>
</head>
<body>
<p>Paragraf pertama</p>
<p>Paragraf kedua</p>
</body>
</html>

Cara atau alternatif lain agar kode DOM kita tidak gagal adalah dengan meletakkan blok kode Javascript di akhir document sebelum tag tutup body karena dijamin semua elemen pasti sudah dirender oleh browser.

    d. Membuat elemen secara dinamis dengan DOM

Sekarang kita buat contoh sederhana pengaplikasian DOM untuk membuat beberapa elemen secara dinamis tanpa mengetikkan secara langsung kode HTMLnya. Saya akan menambahkan tag P (paragraf) dan A (anchor, untuk link) pada elemen body dengan DOM.

<html>
<head>
<title>DOM</title>
<script type="text/javascript">
function buatTagElement(nama) {
    return document.createElement(nama); // membuat element
}
function buatTextElement(teks) {
    return document.createTextNode(teks); // membuat text node
}

window.onload = function(e) {
    var p     = buatTagElement('p'),
        br    = buatTagElement('br'),
        a    = buatTagElement('a'),
        b    = document.getElementsByTagName('body')[0];
    a.href = 'www.posank.com';
    a.appendChild(buatTextElement('posank?'));
    p.style.fontSize = '20px';
    p.appendChild(buatTextElement('kamu'));
    p.appendChild(br);
    p.appendChild(a);
    // hapus elemen sebelumnya
    b.removeChild(document.getElementsByTagName('p')[0]);
    // tambahkan elemen baru
    b.appendChild(p);
}
</script>
</head>
<body>Teks default</body>
</html>

Jika kamu jalankan kode diatas di browser maka akan muncul beberapa elemen yang kita tambahkan secara dinamis seperti pada contoh diatas (kamu posank? :). Untuk dapat melakukan pemrograman menggunakan DOM secara baik diperlukan banyak latihan karena ada banyak kata kunci dan logika yang harus dipelajari dan dilatih. Untuk daftar lengkap method dan property yang digunakan dalam DOM bisa kamu cari di sumber lain atau jika kamu menggunakan browser Google Chrome cukup klik kanan tampilan lalu pilih menu inspect elements atau periksa elemen dan lihat di bagian Elements.

    e. innerHTML
   
innerHTML bukanlah bagian dari DOM tapi property innerHTML sangatlah powerful untuk melakukan beragam operasi pada elemen HTML. Jika pada contoh sebelumnya untuk menghapus atau menambahkan elemen terkesan ribet dan berbelit-belit maka dengan innerHTML kita dapat langsung mengubah isi dari suatu elemen dengan sangat cepat. Perhatikan contoh berikut yang menghasilkan output yang sama dengan kode sebelumnya tapi sekarang kita menggunakan innerHTML.

<html>
<head>
<title>DOM</title>
<script type="text/javascript">
window.onload = function() {
    // string isi yang akan ditambahkan
    var isi = '<p>kamu<br /><a href="www.posank.com">'
            + 'posank?</a></p>';
    // tambahkan isi ke body
    document.getElementsByTagName('body')[0].innerHTML = isi;
    // berikan style ke p
    document.getElementsByTagName('p')[0].style.fontSize = '20px';
}
</script>
</head>
<body>Teks default</body>
</html>

Mudahkan? Nah, bicara soal AJAX, pada umumnya operasi AJAX menggunakan innerHTML ini untuk mengubah sebagian isi dari halaman dengan content dari hasil request yang dilakukan olehnya.

    f. AJAX (Asynchronous JavaScript and XML)
   
Javascript juga dapat melakukan koneksi dibalik layar tanpa kita sadari menggunakan XMLHttpRequest untuk meminta content dari server. Jika kamu menggunakan facebook dan muncul gambar loading lalu tiba-tiba bagian tersebut berubah sendiri maka perubahan tersebut dilakukan dengan AJAX. Karena sifatnya yang Asynchronous itu maka kita tidak perlu merefresh atau mereload keseluruhan halaman tapi Javascript cukup mengubah sebagian elemen menggunakan DOM ataupun innerHTML berdasarkan hasil request yang dilakukannya.

Kamu mungkin tidak perlu tahu kode sesungguhnya untuk melakukan koneksi XMLHttpRequest karena sudah ada banyak class atau framework yang menyediakan interface mudah yang tinggal kamu pakai untuk melakukan koneksi menggunakan AJAX. Tapi jika kamu belum pernah mencoba menggunakan AJAX sama sekali, saya akan berikan source file untuk melakukan koneksi AJAX sederhana menggunakan XMLHttpRequest. Kamu bisa download DISINI. Didalamnya ada tiga file yaitu: "conn.js" sebuah file javascript sebagai penghubung koneksinya, "test.php" sebagai interface contoh koneksinya dan terakhir file "tests.php" sebagai responder bila ada koneksi ajax.

Cara penggunaannya letakkan tiga file tersebut ke webserver atau jika kamu menggunakan mesin lokal dan menggunakan XAMPP letakkan di folder htdocs. Buka browser dan akses file 'test.php' (misal: localhost/test.php). Disitu akan muncul sebuah isian nama yang jika kamu mencoba mengetikkan satu huruf disitu maka akan muncul semacam popup dibawah inputan yang mana isi dari popup ini berasal dari hasil request AJAX ke file 'tests.php'.

Jika saya jelaskan secara detil teknisnya mungkin akan terkesan bertele-tele jadi silakan kamu lihat dan analisa apa dan bagaimana cara melakukan koneksi sederhana menggunakan AJAX. File yang perlu kamu perhatikan adalah file 'test.php' sebagai interfacenya, lalu kamu lihat file 'tests.php' sebagai pemroses dari request yang dikirim oleh file 'test.php' melalui AJAX.

    g. eventListener
   
Pada setiap elemen HTML yang kita buat bisa kita tambahkan event listener yang akan merespon bila ada sebuah event yang terjadi pada element tersebut. Jika kamu pernah menulis atribut "onclick" pada link, maka sebenarnya kamu sudah menambahkan eventlistener pada link tersebut untuk merespon bila terjadi event click. Beberapa event lain antara lain "onchange", "onblur", "onkeypress", "onkeyup", "onload", "onmouseover", dsb. Dengan DOM kita bisa menambahkan eventlistener pada hampir semua elemen dengan menggunakan method addEventListener() pada node yang ada. Method ini mememiliki tiga parameter yaitu:
    1. nama event (tanpa kata "on")
    2. nama fungsi yang dipanggil bila event terjadi
    3. apakah menggunakan capture (true jika iya, false jika menggunakan bubbling)
contohnya adalah seperti: box.addEventListener('click', expand, false) yang berarti kita menambahkan eventlistener pada node box untuk event click yang akan memanggil fungsi expand dan jenis event yang digunakan adalah bubbling. Berikut ini saya buatkan contoh pengaplikasian eventlistener dan DOM untuk membuat animasi sederhana di halaman web.
   
<html>
<head>
<title>Animasi</title>
<script type="text/javascript">
var c = {
    'i'            : null,
    'box'        : null,
    'state'        : 'b',
    'init'        : function() {
        this.box = document.getElementById('box');
        this._setStyle();
        this.box.addEventListener('click', c.ubahUkuran, false);
    },
    '_setStyle'    : function() {
        var bs = this.box.style;
        bs.width = '300px';
        bs.height = '300px';
        bs.margin = '20px auto';
        bs.border = '1px solid #000';
        bs.background = 'orange';
    },
    'ubahUkuran': function() {
        var w = parseInt(c.box.style.width.replace('px', ''));
        var l = c.state == 'b' ? 80 : 300;
        if (w == l) {
            clearInterval(c.i);
            c.i = null;
            c.state = c.state == 'b' ? 's' : 'b';
            c.box.addEventListener('click', c.ubahUkuran, false);
            return;
        } else {
            w = c.state == 'b' ? w - 5 : w + 5;
            c.box.style.width = w + 'px';
            c.box.style.height = w + 'px';
            c.box.removeEventListener('click', c.ubahUkuran, false);
        }
        if (c.i == null)
            c.i = setInterval(c.ubahUkuran, 13);
    }
}
window.onload = function() {
    c.init();
}
</script>
</head>
<body><div id="box"></div>
</body>
</html>

Coba kamu klik kotak yang ada di tengah halaman web dari hasil kode diatas maka kotak berwarna oranye tersebut akan mengecil. Klik sekali lagi maka kotak kembali membesar dan begitu seterusnya.

    h. Membuat teks berkedip dan bergerak dengan DOM dan CSS

Sekarang kita buat sesuatu yang real yang bisa kita rasakan kegunaan dari DOM. Untuk membuat animasi ini kamu harus sedikit paham tentang Cascading Style Sheet (CSS) karena yang kita lakukan hanya mengubah-ubah properti CSS pada elemen yang akan kita animasikan. Kode lengkapnya adalah seperti berikut:

<html>
<head>
<title>Animasi</title>
<style type="text/css">
#wadah { width: 90%; margin: 50px 5%; position: relative; }
#teks {
    font: bold 20px 'lucida grande', sans-serif;
    position: absolute; left: 0px; opacity: 1.0;
}
</style>
<script type="text/javascript">
// object untuk animasi
var anim = {
    intval        : null, // timer untuk animasi
    objek        : null, // objek dari elemen
    state        : ['dim', 'right'], // opacity dan arah gerakan
    speed        : 3, // kecepatan gerakan
    stop        : function() {
        clearInterval(anim.intval);
        anim.intval = null;
        anim.init();
    },
    init        : function() {
        if (this.objek == null)
            this.objek = document.getElementById('teks');
        // kecepatan animasi per 20 milisecond
        this.intval = setInterval(anim.animasi, 20);
    },
    animasi        : function() {
        // untuk berkedip gunakan opacity, IE 6 gak bisa!
        var opac = parseFloat(getComputedStyle(anim.objek, null).opacity);
        opac = anim.state[0] == 'dim' ? opac - 0.1 : opac + 0.1;
        if (opac == 0.1)
            anim.state[0] = 'highlight';
        if (opac == 1)
            anim.state[0] = 'dim';
        anim.objek.style.opacity = opac;
       
        // untuk bergerak gunakan left
        var left = parseInt(getComputedStyle(anim.objek, null).left.replace('px', ''));
        left = anim.state[1] == 'right' ? left + anim.speed : left - anim.speed;
        if (left > 500)
            anim.state[1] = 'left';
        if (left < 0)
            anim.state[1] = 'right';
        anim.objek.style.left = left + 'px';
       
        // refresh counter
        if (anim.intval > 500)
            anim.stop();
    }
};
window.onload = function() {
    anim.init();
}
</script>
</head>
<body>
<div id="wadah">
    <div id="teks">Teks ini terus bergerak dan berkedip</div>
</div>
</body>
</html>

Oh iya, kode diatas tidak akan dapat berjalan di browser Internet Explorer 6 bawaan XP jadi kamu harus gunakan browser lain yang lebih standar dan mendukung DOM seperti Firefox atau Chrome.

    i. DOM di PHP

DOM tidak hanya ada di JavaScript tapi PHP juga memiliki beberapa class untuk beroperasi dengan DOM. Nama method yang digunakan juga hampir sama seperti getElementById, dsb. jadi jika kamu terbiasa dengan DOM menggunakan JavaScript maka dijamin akan dengan mudah menggunakan fitur DOM di PHP. Berikut ini saya beri contoh kode PHP sederhana untuk membuat dokumen HTML dengan DOM (hasilnya akan sama dengan DOM Javascript pada contoh sebelumnya):

<?php
function buatTagElement($o, $e = '') { return $o->createElement($e); }
function buatTextElement($o, $s = '') { return $o->createTextNode($s); }

$html = '<html>
<head>
<title>Cek</title>
</head>
<body></body>
</html>';

$doc = new DOMDocument('1.0');
$doc->loadHTML($html);

$p     = buatTagElement($doc, 'p');
$br    = buatTagElement($doc, 'br');
$a    = buatTagElement($doc, 'a');
$b     = $doc->getElementsByTagName('body')->item(0);
$a->setAttribute('href', 'www.posank.com');
$a->appendChild(buatTextElement($doc, 'posank?'));
$p->setAttribute('style', 'font-size: 20px');
$p->appendChild(buatTextElement($doc, 'kamu'));
$p->appendChild($br);
$p->appendChild($a);
$b->appendChild($p);

echo $doc->saveHTML();
?>

    j. Kesimpulan :)
   
Jika kamu berminat menjadi web designer yang ingin membuat halaman yang dinamis dan menarik maka pengetahuan tentang DOM mutlak kamu kuasai. Dengan DOM kamu bisa memanipulasi semua elemen yang ada pada dokumen, mengubah atributnya, menambah elemen baru atau menghilangkan elemen yang lain serta membuat animasi ringan dengan Javascript dan CSS. Semua animasi yang pernah kamu lihat pada website modern pasti menggunakan DOM (kecuali animasinya pakai Flash). Pertama mungkin terkesan ruwet dan banyak yang harus dipelajari tapi begitu kamu masuk sedikit kedalam DOM maka kamu akan merasa ketagihan dan dibuat terkagum-kagum dengan hasil kerjamu :D.

Pembahasan berikutnya kita akan membahas jQuery, sebuah framework Javascript yang membuat kerjamu dengan DOM akan semudah membalik telapak tangan. Membuat animasi, memanipulasi elemen, semua dilakukan dengan sedikit kode dan logika jika kamu menggunakan jQuery. Sekian dulu pembahasan kali ini dan sampai jumpa!!

2 komentar:

  1. saya blum mengerti tentang DOM... mungkin ada tutorial atau penjelasan mengenai DOM dan contoh-contoh sederhana... jazakallah

    BalasHapus
    Balasan
    1. Sebenarnya konsep DOM tidak harus dipelajari sampai detil karena sekarang banyak framework seperti jQuery dan semacamnya yang dapat melakukan manipulasi DOM dengan sedikit kode. Untuk tutorial saya tidak ada rujukan pasti :D, coba googling, atau ke situs http://alistapart.com, ada banyak tutorial css dan javascript disitu.

      Hapus