Contents
Pendahuluan Event
Kita telah mempelajari Browser Object Model, Document Object Model, penggunaan BOM untuk membangkitkan fungsionalitas khusus dari browser, dan cara menggunakan DOM untuk memanipulasi atau mengubah konten dari sebuah berkas HTML.
Lalu, bagaimana JavaScript menjalankan serangkaian perintah jika user berinteraksi dengan salah satu elemen HTML pada halaman web? Misalnya, menampilkan pesan menggunakan method alert() ketika user menekan sebuah tombol pada halaman web atau mengubah tampilan halaman web jika user menekan sebuah key khusus pada keyboard?
Solusinya terdapat pada materi ini, mari berkenalan dengan event!
Ketika browser selesai menampilkan halaman web, menekan tombol tertentu pada keyboard, atau mungkin meletakkan kursor pada elemen HTML tertentu, itulah yang dinamakan event alias “kejadian”. Hampir apa pun yang berhubungan dengan adanya interaksi dengan berkas HTML bisa kita sebut sebagai event. Lalu, apa fungsinya?
Melalui JavaScript, kita bisa menulis kode tertentu yang akan dijalankan ketika merasakan sebuah “kejadian” tertentu. Contohnya jika user menekan sebuah tombol, JavaScript (melalui DOM) akan mengubah tampilan halaman web kita seperti mengubah warna pada elemen tertentu, atau bahkan membawa kita ke bagian tertentu pada halaman web tersebut. Sebagai contoh, ketika elemen button ini ditekan, akan memunculkan dialog box dengan pesan "Halo! Apa Kabar".
<button onclick="alert('Halo! Apa Kabar')">Tekan Aku</button>
Penambahan event di atas akan menghasilkan hal seperti berikut.
Keren, bukan?
Untuk materi Event, kita akan membahas mengenai:
- Macam-macam Event.
- Membuat kode JavaScript untuk menjalankan kode berdasarkan event tertentu.
- Memberikan kemampuan sebuah elemen HTML untuk membuat sebuah event.
- Memberikan kemampuan sebuah elemen HTML untuk bereaksi terhadap event.
- Membuat Custom Event, yakni event yang sudah dimodifikasi sesuai dengan keperluan kita.
Ketika sudah memahami bagaimana cara menggunakan event dan mengimplementasikannya bersama dengan manipulasi melalui DOM dan BOM, maka dijamin halaman web Anda sangat interaktif dan tidak terkesan “hambar”. Semangat!
Macam-Macam Event
Walau istilah event terkesan sangat abstrak, kita dapat menggolongkan beberapa event menjadi beberapa kategori berdasarkan sumber dari mana event tersebut terjadi. Contohnya kejadian yang berhubungan dengan kursor mouse, keyboard, kegiatan copy sebuah elemen teks pada berkas HTML, atau bahkan dari ukuran window browser.
Berikut beberapa pembahasan terhadap kategori umum serta beberapa event-event yang tergolong pada kategori tersebut.
Window Events
Window Events adalah kejadian-kejadian yang berasal dari browser alias pada window.
Nama Event | Penjelasan |
---|---|
onload | Event ini akan terjadi setelah halaman web selesai diunduh dan ditampilkan. |
onpageshow | Event ini akan terjadi jika halaman web kembali dikunjungi kembali (berbeda dengan onload, karena event onload tidak akan terjadi jika halaman web diambil dari cache). |
onresize | Event ini akan terjadi jika window browser di-resize oleh user atau oleh hal lainnya. |
Form Events
Form Events adalah kejadian-kejadian yang berasal dari sebuah elemen HTML dengan tag <form> (kita akan mempraktikkan penggunaan tag <form> pada materi Form Event.)
Nama Event | Penjelasan |
---|---|
onreset | Event ini akan terjadi ketika user menekan tombol ‘reset’’ pada elemen form. |
onsubmit | Event ini akan terjadi ketika user menekan tombol ‘submit’’ pada form. |
Keyboard Events
Keyboard Events adalah kejadian-kejadian yang berasal dari ditekan atau dilepasnya tombol pada keyboard.
Nama Event | Penjelasan |
---|---|
onkeydown | Event ini akan terjadi ketika sebuah tombol pada keyboard ditekan. |
onkeypress | Event ini terjadi setelah onkeydown, di mana tombol masih dalam keadaan ditekan. Event ini tidak dapat mendeteksi tombol fungsi seperti CTRL, SHIFT, ALT, ESC, BACKSPACE, dan sebagainya. |
onkeyup | Event ini akan terjadi ketika sebuah tombol pada keyboard dilepas. |
Clipboard Events
Clipboard Events adalah kejadian-kejadian yang berasal dari proses cut, copy, atau paste sebuah elemen.
Nama Event | Penjelasan |
---|---|
oncopy | Event ini akan terjadi ketika kita melakukan proses copy. |
oncut | Event ini akan terjadi ketika kita melakukan proses cut. |
onpaste | Event ini akan terjadi ketika kita melakukan proses paste. |
Mouse Events
Mouse Events adalah kejadian-kejadian yang berasal dari kegiatan klik mouse.
Nama Event | Penjelasan |
---|---|
onclick | Event ini akan terjadi ketika kita menekan elemen tertentu dengan cursor. |
ondblclick | Event ini akan terjadi ketika kita menekan elemen tertentu dua kali berturut-turut dengan cursor. |
onmouseover | Event ini akan terjadi cursor kita berada di atas sebuah elemen tertentu. |
Sekian macam-macam event yang umum. Terdapat beberapa event yang akan kita gunakan pada bagian praktik materi event sehingga tidak perlu dihafalkan semuanya sekaligus. Melalui praktik nanti, diharapkan Anda dapat menghafalnya perlahan.
Menambahkan Event Handler
Menyiapkan Halaman Website
Cukup banyak event yang bisa kita gunakan untuk menambah aspek interaktif dalam halaman web. Walau sangat banyak, kita hanya akan mempraktikkan 2 event saja, yakni event onclick dan onload.
Sebelum melanjutkan materi, kita harus menyiapkan sebuah berkas HTML dan strukturnya. Silakan beri nama berkas HTML tersebut dengan “event.html”.
<!DOCTYPE html> <html> <head> <title>Event World</title> <style> .contents { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } #generateButton { margin-top: 5px; margin-bottom: 15px;; } </style> </head> <body> <div class="contents" align="center" hidden> <button id="incrementButton">Tekan Aku :)</button> <h3>Kamu sudah menekan tombol di atas sebanyak <span id="count">0</span></h3> </div> <script> // Kode JavaScript kita </script> </body> </html>
Pada tag <div> terdapat atribut align dengan nilai center yang berfungsi untuk memosisikan seluruh child element berada di tengah-tengah parent element-nya. Namun, penggunaan atribut ini sudah usang (deprecated) sehingga penggunaannya sudah tidak di rekomendasikan kembali. Solusinya adalah menuliskan aturan styling menggunakan CSS.
Tampilannya berupa halaman web yang hampa akan konten. Mengapa demikian? Tenang, browser Anda tidak rusak. Tampilannya memang kosong karena elemn <div> menerapkan atribut hidden. Kita akan menambahkan event handler, yang merupakan kode JavaScript yang akan dijalankan ketika sebuah event tertentu terjadi, yakni event onload dan onclick. Ketika kita sudah mencapai tahap akhir dari praktik di bawah, siap-siap takjub terhadap halaman web yang berperilaku seperti ini:
Pada materi ini, akan ada perbedaan pada aspek praktik. Jika sebelumnya kita menulis kode JavaScript menggunakan console browser, sekarang kita akan sepenuhnya menggunakan text editor. Maka keluarkan text editor favorit Anda!
Membuat event handler onload
Oke deh, tugas pertama kita adalah memunculkan semua konten HTML setelah semua baris pada berkas HTML diproses oleh browser di mana event onload akan terjadi. Pada bagian tag <script>, kita akan menulis kode perintah, yang mana akan dijalankan ketika event onload terjadi pada elemen body. Kode perintah tersebut disebut sebagai event handler dari event onload.
Bagaimana membuat sebuah event handler untuk elemen tertentu? Tenang, kita akan membahas satu per satu dengan dimulai dari membuat sebuah fungsi event handler hingga “mengaitkan” fungsi tersebut supaya berjalan ketika event onload terjadi pada elemen body.
Cobalah buka berkas HTML dan deklarasikan function baru bernama welcome yang akan menghapus atribut hidden pada elemen <div> ketika elemen body selesai diproses oleh browser lalu menjalankan event onload. Fungsi tersebut diletakkan di antara tag <script>.
function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); }
Pada kode di atas, kita akan memunculkan sebuah dialog box alert. Fungsi dari dialog box adalah memberitahu user bahwa elemen HTML yang sebelumnya bersembunyi akan ditampilkan. Caranya adalah dengan menghilangkan atribut hidden dari elemen <div>. Untuk menghilangkan atribut hidden, gunakan method removeAttribute() dari elemen yang dituju.
Mendekati akhir dari penutup tag </script>, kita perlu menambah kode event handler untuk event onload dari elemen body. Pada umumnya, menambahkan sebuah event handler pada sebuah event yang berasal dari sebuah elemen HTML tertentu akan menggunakan pendekatan seperti berikut.
elemen.{nama_event} = namaFunction();
Pada kasus menulis event handler onload di sini, kode yang digunakan untuk memberikan event pada elemen body adalah sebagai berikut.
document.body.onload = welcome;
Saat ini kode kita akan menjadi seperti berikut.
<script> function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } document.body.onload = welcome; </script>
Jika kita jalankan lagi melalui browser, maka akan muncul alert dengan pesan “sim salabim muncullah elemen-elemen HTML”.
Mantab! Semua elemen HTML seketika muncul. Langkah selanjutnya adalah menambahkan event handler untuk event onclick pada tombol “Tekan Aku :)”. Jika saat ini kita tekan tombolnya, tidak ada respon yang terjadi.
Membuat event handler onclick
Sebelumnya kita telah mengimplementasikan event handler onload pada elemen body. Namun, mengapa ketika menekan tombol “Tekan Aku :)” tidak terjadi apa-apa? Hal ini dikarenakan kita belum memberikan event handler.
Pada praktik ini, kita akan mengubah angka dalam teks untuk menampilkan berapa kali user menekan tombol. Caranya adalah memberikan event listener kepada button. Selain itu, kita juga akan memberikan kejutan lucu ketika user sudah menekan tombol hingga 7 kali. Penasaran? Mari kita langsung ngoding!
Buka berkas HTML yang sebelumnya sudah dibuat. Pada tag <script>, deklarasikan function increment() yang akan melakukan proses increment atau kenaikan angka sebagai jumlah berapa kali user menekan tombol. Ini dilakukan melalui event onclick. Silakan tambahkan kode seperti berikut.
function increment() { document.getElementById('count').innerText++; }
Pada kode di atas, kita memerintahkan agar teks melakukan proses increment (++) pada elemen yang memiliki atribut id dengan value count. Silakan tambahkan event handler pada elemen button seperti berikut.
document.getElementById('incrementButton').onclick = increment;
Keren nih. Sekarang setiap kali tombol ditekan angka "0" semakin bertambah.
Mantab! Sekarang tombol sudah berjalan sebagaimana mestinya. Sekarang saatnya kita menambahkan fitur kejutan ketika tombol ditekan hingga 7 kali. Mari modifikasi fungsi increment() menjadi seperti berikut.
function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } }
Kita telah menambahkan kode pada function increment(). Kegunaannya adalah function ini akan memeriksa apakah jumlah tekanan pada tombol sudah sama dengan 7. Jika iya, event handler tersebut akan menambahkan dua elemen baru, yakni elemen <h4> yang berisi suatu pesan dan elemen <img> yang berupa gambar.
Dengan begitu, isi dari tag <script> di atas akan seperti berikut.
<script> function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } } function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } document.getElementById('incrementButton').onclick = increment; document.body.onload = welcome; </script>
Sehingga, halaman web kita akan memiliki semua fungsionalitas seperti yang diperlihatkan di awal.
Halaman web kita sudah menjadi sangat interaktif dan menarik hanya melalui beberapa kode JavaScript saja. Coba-lah bereksperimen dengan menambahkan beberapa event pada elemen-elemen baru serta event handler-nya juga.
Menerapkan event handler inline
Mungkin Anda sudah sangat familiar dengan istilah inline. Tahukah Anda bahwa kita bisa menerapkan event handler di dalam tag HTML dan tidak perlu menerapkan sintaks event handler dalam tag <script>?
Coba berikan tanda komentar terlebih dahulu pada kode event handler di dalam berkas HTML yang baru kita selesaikan.
<script> function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } } function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } // document.getElementById('incrementButton').onclick = increment; // document.body.onload = welcome; </script>
Jika sudah, maka halaman web telah kehilangan semua fitur yang telah kita implementasikan sebelumnya. Tenang, semua fiturnya akan kita kembalikan melalui inline event handler, yakni menulis event handler melalui atribut tag HTML (onload dan onclick).
Tambahkan event handler pada tag <body> dan <button> sebagai berikut:
<!DOCTYPE html> <html> <head> <title>Event World</title> <style> .contents { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } #generateButton { margin-top: 5px; margin-bottom: 15px;; } </style> </head> <body onload="welcome()"> <div class="contents" align="center" hidden> <button id="incrementButton" onclick="increment()">Tekan Aku :)</button> <h3>Kamu sudah menekan tombol di atas sebanyak <span id="count">0</span></h3> </div> <script> function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } } function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } // document.getElementById('incrementButton').onclick = increment; // document.body.onload = welcome; </script> </body> </html>
Pada tag <div> terdapat atribut align dengan nilai center yang berfungsi untuk memosisikan seluruh child element berada di tengah-tengah parent element-nya. Namun, penggunaan atribut ini sudah usang (deprecated) sehingga penggunaannya sudah tidak di rekomendasikan kembali. Solusinya adalah menuliskan aturan styling menggunakan CSS.
Simpan semua perubahan pada berkas event.html dan jalankan kembali. Tada! Semua fungsionalitas telah kembali seperti semula.
Sampai di sini kita sudah mengetahui bagaimana menerapkan event handler untuk elemen-elemen HTML. Namun, ada satu lagi trik untuk menerapkan hal yang serupa dengan event handler yakni melalui method addEventListener(). Penasaran? Yuk, kita lanjut ke materi berikutnya.
Menerapkan Event Handler dengan addEventListener()
Kali ini kita akan mempelajari menerapkan event handler menggunakan function addEventListener. Pertama, sesuaikan berkas event.html sebelumnya dengan kode sebagai berikut.
<!DOCTYPE html> <html> <head> <title>Event World</title> <style> .contents { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } #generateButton { margin-top: 5px; margin-bottom: 15px;; } </style> </head> <body> <div class="contents" align="center" hidden> <button id="incrementButton">Tekan Aku :)</button> <h3>Kamu sudah menekan tombol di atas sebanyak <span id="count">0</span></h3> </div> <script> function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } } function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } // kita akan menulis kode menggunakan addEventListener di sini </script> </body> </html>
Method addEventListener() menerima beberapa parameter, tetapi yang perlu kita ketahui sementara adalah parameter pertama dan kedua. Parameter pertama harus diisi dengan tipe event yang digunakan, yang mana akan men-trigger atau memancing kode JavaScript untuk menjalankan sebuah fungsi khusus. Function khusus diletakkan pada parameter kedua yang akan dijalankan ketika tipe event yang didefinisikan terjadi.
Ada satu aturan yang perlu kita ketahui, yaitu nama event yang kita definisikan tidak seperti sebelumnya menggunakan onload dan onclick (tanpa imbuhan "on"). Namun, kita dapat menuliskannya secara langsung. Sebagai contoh function onload menjadi ‘load’, function onclick menjadi ‘click’. Untuk daftar lengkap event apa saja yang yang didukung dapat dilihat di sini: https://developer.mozilla.org/en-US/docs/Web/Events.
Okay, kita sudah mengetahui teknis seputar method addEventListener(). Berikutnya kita akan sepenuhnya fokus latihan. Tambahkan kode berikut
// kita akan menulis kode menggunakan addEventListener di sini window.addEventListener('load', welcome); document.getElementById('incrementButton').addEventListener('click', increment);
Mungkin Anda bertanya-taya, "mengapa event load dipasangkan ke obyek window?". Jawabannya adalah method addEventListener() tidak bisa bekerja pada tag <body> sehingga kode akan berbentuk seperti berikut.
<script> function increment() { document.getElementById('count').innerText++; if (document.getElementById('count').innerText == 7) { const hiddenMessage = document.createElement('h4'); hiddenMessage.innerText = 'Selamat! Anda menemukan hadiah tersembunyi...'; const image = document.createElement('img'); image.setAttribute('src', 'https://i.ibb.co/0V49VRZ/catto.jpg'); const contents = document.querySelector('.contents'); contents.appendChild(hiddenMessage).appendChild(image); } } function welcome() { alert('Sim salabim muncullah elemen-elemen HTML!'); const contents = document.querySelector('.contents'); contents.removeAttribute('hidden'); } window.addEventListener('load', welcome); document.getElementById('incrementButton').addEventListener('click', increment); </script>
Jalankan kembali berkas HTML di atas, ia pasti akan berfungsi normal kembali! Lantas, jika sama dengan inline event handler, apa keuntungan lebih yang ditawarkan method addEventListener()? Kelebihannya adalah kita bisa menambahkan satu atau lebih fungsi sebagai event handler. Fitur itulah yang tidak dapat dilakukan oleh event handler inline.
<script> // contoh penerapan element.onclick = fungsiA; element.onclick = fungsiB; </script>
Selain itu, terdapat permasalahan lagi jika tidak menggunakan addEventListener. Kode di atas, kita memanggil function onclick dan melakukan assignment dengan fungsiA dan fungsiB. Sayangnya, fungsiA ini akan ter-overwrite alias tertimpa fungsiB. Oleh karena itu, jika elemen di-klik, hanya fungsiB saja yang dijalankan. Bagaimana cara kita menemukan solusi agar fungsiA dan fungsiB dijalankan ketika elemen di-klik? Gunakanlah method addEventListener()!
<script> // contoh penerapan element.addEventListener('click', fungsiA); element.addEventListener('click', fungsiB); </script>
Selain mampu menambahkan multiple event listener dalam satu event, kita juga akan mempelajari penerapan method addEventListener() lebih tepat untuk skenario-skenario tertentu ketimbang menggunakan event handler yang dicontohkan sebelumnya. Method addEventListener() juga mendukung fitur “event bubbling dan capturing” yang akan kita bahas nantinya.
Menambahkan Custom Event
Apa yang dimaksud dengan Custom Event? Custom Event pada materi ini merujuk kepada penggunaan class Event() untuk membuat event dengan nama yang sudah kita tentukan sendiri. Misal, sebelumnya kita telah menggunakan nama-nama event yang sudah “dikenal” oleh JavaScript yakni seperti “click” dan “load’. Apakah mungkin jika kita membuat event sendiri? Misalnya, event dengan nama "eventBuatanKita"? Jawabannya, sangat mungkin! Mari kita lihat sintaks berikut.
// membuat custom event const eventBuatan = new Event('eventBuatanKita'); // meletakkannya pada sebuah method addEventListener() element.addEventListener('eventBuatanKita');
Kode di atas menunjukkan kepada kita cara membuat custom event dan menerapkannya pada event listener. Jika Anda bertanya-tanya, “Kenapa kita harus mempelajari custom event?" Jawabannya adalah tidak seperti event yang biasanya “dikenali” oleh method addEventListener, custom event memungkinkan kita untuk menjalankan sebuah event handler setelah sebuah event handler lain selesai dipanggil.
Daripada kita berlama-lama, mari kita langsung praktikkan. Pertama buatlah sebuah berkas HTML dengan isi sebagai berikut.
<!DOCTYPE html> <html> <head> <title>Event World</title> <style> .buttons { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } .button { margin: 8px; height: 40px; } </style> </head> <body> <div class="buttons" align="center"> <h3 id="caption">Silakan tekan salah satu tombol di bawah...</h3> <button class="button" id="tombol">Tombol Custom Event</button> </div> <script> // tulis kode kamu di sini </script> </body> </html>
Silakan simpan kode HTML di atas dengan nama “custom-event.html”. Pada awal isi dari tag <script>, buatlah variabel baru dan inisialisasikan dengan custom event yang bernama “changeCaption”.
const changeCaption = new Event('changeCaption');
Kemudian tambahkan sebuah event listener untuk custom event dan event listener pada button melalui method addEventListener() ketika tombol tersebut ditekan.
window.addEventListener('load', function() { const tombol = document.getElementById('tombol'); tombol.addEventListener('changeCaption', customEventHandler); tombol.addEventListener('click', function() {}); });
Pada tahap terakhir kita akan mendeklarasikan function customEventHandler yang dijalankan ketika event changeCaption terjadi.
function customEventHandler(ev) { console.log('Event ' + ev.type + ' telah dijalankan'); const caption = document.getElementById('caption'); caption.innerText = 'Anda telah membangkitkan custom event'; }
Fungsi dari customEventHandler memiliki 1 parameter yang bernama “ev”. Apa itu “ev”? Secara otomatis, parameter “ev” berisi obyek event (“ev” merupakan singkatan dari “event”). Dengan obyek ini, kita dapat memeroleh banyak informasi mengenai elemen yang terkait. Semua ini akan dilakukan secara otomatis oleh JavaScript.
Jadi, kode terakhir di dalam tag <script> akan seperti berikut.
<script> const changeCaption = new Event('changeCaption'); window.addEventListener('load', function() { const tombol = document.getElementById('tombol'); tombol.addEventListener('changeCaption', customEventHandler); tombol.addEventListener('click', function() {}); }); function customEventHandler(ev) { console.log('Event ' + ev.type + ' telah dijalankan'); const caption = document.getElementById('caption'); caption.innerText = 'Anda telah membangkitkan custom event'; } </script>
Tampilan web ketika dijalankan akan terlihat seperti di bawah ini.
Sederhana, bukan? Walaupun kita sudah menerapkan custom event, mengapa tidak menghasilkan perubahan apa pun ketika tombol ditekan? Jawabannya adalah kita belum membuat fungsi untuk eventHandler pada event “click” pada tombol tersebut. Mari lengkapi kode kita pada materi berikutnya!
Best Practice untuk Custom Event
Saat kita membuat custom event, mungkin saja kita secara bebas membuat event di manapun dengan nama yang sudah kita tentukan secara sembarang! Sebelum Anda melakukan hal tersebut, kita perlu tahu mengapa hal seperti itu tidak baik untuk dijadikan kebiasaan. Hal tersebut akan berpotensi menyebabkan bug dan penyelesaiannya akan semakin sulit seiring semakin kompleksnya program kita.
Untuk mencatat custom event apa saja yang telah dibuat, sebaiknya buatlah sebuah variabel konstanta yang menyimpan semua nama custom event. Hal tersebut dilakukan supaya tidak ada kejadian yang tidak diinginkan. Salah satu resikonya adalah ter-overwrite dengan suatu custom event yang sama sehingga kita perlu memberitahu dan membuat kesepakatan dengan rekan programmer lain tentang hal tersebut.
Membangkitkan Custom Event
Di sini kita akan membangkitkan custom event yang sudah dibuat pada materi sebelumnya. Dalam praktik ini, kita tidak perlu menambahkan banyak kode, melainkan hanya fungsi yang berisi proses dispatch atau pemanggilan custom event handler.
Sebelum melangkah lebih jauh, pastikan Anda membuka berkas HTML custom-event.html yang sudah dibuat sebelumnya. Pastikan kembali kodenya sesuai dengan seperti berikut ini.
<!DOCTYPE html> <html lang="id"> <head> <title>Event World</title> <style> .buttons { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } .button { margin: 8px; height: 40px; } </style> </head> <body> <div class="buttons" align="center"> <h3 id="caption">Silakan tekan salah satu tombol di bawah...</h3> <button class="button" id="tombol">Tombol Custom Event</button> </div> <script> const changeCaption = new Event('changeCaption'); window.addEventListener('load', function () { const tombol = document.getElementById('tombol'); tombol.addEventListener('changeCaption', customEventHandler); tombol.addEventListener('click', function () {}); }); function customEventHandler(ev) { console.log('Event ' + ev.type + ' telah dijalankan'); const caption = document.getElementById('caption'); caption.innerText = 'Anda telah membangkitkan custom event'; } </script> </body> </html>
Sudah sesuai dengan kode di atas? Jika sudah, kita akan memanggil function dispatchEvent() untuk trigger custom event yang telah dideklarasikan dan dipasangkan, yaitu changeCaption. Caranya adalah masukkan argument pada function dispactEvent() dengan variabel changeCaption. Jadi, hasilnya adalah sebagai berikut.
tombol.addEventListener('click', function () { tombol.dispatchEvent(changeCaption); });
Dengan demikian, kode JavaScript di dalam tag <script> secara keseluruhan menjadi seperti berikut.
<script> const changeCaption = new Event('changeCaption'); window.addEventListener('load', function () { const tombol = document.getElementById('tombol'); tombol.addEventListener('changeCaption', customEventHandler); tombol.addEventListener('click', function () { tombol.dispatchEvent(changeCaption); }); }); function customEventHandler (ev) { console.log('Event ' + ev.type + ' telah dijalankan'); const caption = document.getElementById('caption'); caption.innerText = 'Anda telah membangkitkan custom event'; } </script>
Simpan berkas HTML dan buka kembali. Jika tombol yang muncul ditekan, teks di atas tombol akan berubah. Selain itu, console.log() juga dijalankan dan muncul log pada console browser.
Sama halnya dengan event listener pada umumnya. Jika tidak menampilkan event melalui elemen lain yang tidak sama dengan elemen yang memiliki event listener, function customEventHandler tidak akan dijalankan (invoked). Sebagai contoh jika kita memanggil fungsi event handler melalui elemen lain, event handler tidak akan memproses event-nya.
Tidak jauh berbeda dengan menerapkan event yang sudah “dikenal” oleh JavaScript seperti onclick dan onload, bukan?
Melalui event, ada fenomena yang harus kita pelajari yang disebut “bubbling” dan “capturing”. Jika tidak diantisipasi, besar kemungkinan terjadi bug pada berkas HTML yang memiliki nested element alias elemen yang berada di dalam elemen (elemen bersarang).
Event Bubbling dan Capturing
Di mana ada event maka kemungkinan ada bubbling dan capturing. Pada kesempatan kali ini, kita akan membahas mengenai apa itu bubbling dan capturing serta mempraktikkannya. Event bubbling maupun capturing termasuk dalam event propagation. Untuk mengetahui lebih lanjut, mari kita bahas event Bubbling dan Capturing pada uraian di bawah ini:
Bubbling
Apakah Anda pernah melihat gelembung udara muncul dari dasar minuman bersoda ketika dituang ke sebuah gelas? Pasti gelembung udara tersebut akan bergerak perlahan menuju ke permukaan, bukan? Ingat baik-baik analogi ini bahwa gelembung udara akan selalu naik ya.
Sama halnya dengan gelembung udara, fenomena bubbling adalah ketika sebuah event terjadi pada sebuah elemen, maka event handler milik elemen tersebut akan dijalankan terlebih dahulu yang diikuti event handler elemen parent-nya, dan seterusnya sampai elemen paling atas. Sama seperti fenomena gelembung udara pada minuman bersoda, bukan?
Bagaimana contoh riilnya? Mari kita buat sebuah berkas HTML sederhana seperti berikut:
<!DOCTYPE html> <html lang="en"> <head> <title>Bubbling World</title> <style> body * { margin: 8px; padding: 5px; border: 2px solid black; width: 60%; } </style> </head> <body> <div onclick="alert('ELEMEN LANGIT')" align="center"> LANGIT <div onclick="alert('ELEMEN LUAR')" align="center"> LUAR <div onclick="alert('ELEMEN TENGAH')" align="center"> TENGAH <div onclick="alert('ELEMEN DALAM')" align="center"> DALAM </div> </div> </div> </div> </body> </html>
Klik pada tag <div> dengan innerText bernilai “DALAM” lalu perhatikan apa yang terjadi.
Kenapa berperilaku demikian? Perhatikan kembali setiap tag <div> pada berkas HTML di atas. Semua elemen memiliki event handler untuk event onclick. Sesuai dengan penjelasan bubbling, jika kita menekan elemen paling dalam, maka semua event handler akan dijalankan dimulai dari elemen pertama yang di-klik lalu kemudian parent-nya dan seterusnya.
Sekarang coba tekan daerah elemen yang terdapat tulisan “TENGAH”, maka event handler yang dijalankan hanyalah milik elemen tersebut serta parent-parentnya dan tidak termasuk child-nya. Alur tersebut sama seperti prinsip gelembung udara udara yang hanya bergerak ke atas dan tidak ke bawah.
Capturing
Setelah membahas bubbling, mari kita bahas fenomena berikutnya yakni capturing. Capturing merupakan kebalikan dari bubbling yang akan men-trigger event handler dari parent ke child.
Mari kita buat sebuah berkas HTML baru bernama capturing.html beserta strukturnya.
<!DOCTYPE html> <html lang="en"> <head> <title>Capturing World</title> <style> body * { margin: 8px; padding: 5px; border: 2px solid black; width: 60%; } </style> </head> <body> <div align="center" id="langit"> LANGIT <div align="center" id="luar"> LUAR <div align="center" id="tengah"> TENGAH <div align="center" id="dalam"> DALAM </div> </div> </div> </div> <script> // tulis kode Anda di sini </script> </body> </html>
Sekarang tambahkan kode berikut pada bagian script.
const divs = document.getElementsByTagName('div'); for (let el of divs) { el.addEventListener('click', function() { alert('ELEMEN ' + el.getAttribute('id').toUpperCase()); }, true); }
Kode di atas akan menambahkan event listener melalui addEventListener terhadap semua elemen div pada berkas HTML. Isi dari event handler adalah nama id elemen tersebut diubah semua ke huruf besar. Fungsionalitas sama persis dengan cara yang kita terapkan pada bubbling.html, hanya saja kita menggunakan method addEventListener ketimbang inline.
Kenapa kita menggunakan addEventListener? Karena melalui addEventListener, kita bisa memberikan satu parameter khusus bernilai boolean ke parameter ke-3 seperti yang ditunjukkan kode yang dicetak tebal di atas, yaitu true.
Sekarang mari kita buka kembali berkas HTML pada browser.
Perhatikan ketika kita klik sebuah elemen, maka dialog box alert yang muncul dimulai dari elemen paling luar dan berhenti di elemen yang kita tekan. Persis dengan kebalikan dari bubbling, bukan?
Pengenalan ke Form
Sejauh ini kita sudah mempelajari bagaimana cara menambahkan aspek interaktif dari halaman web, terutama mengubah layout-nya. Sebelum kita menyelesaikan modul ini, ada satu jenis elemen HTML yang sangat sering digunakan untuk mengumpulkan banyak input dari user sekaligus. Kita sudah pernah menyebutnya pada materi-materi sebelumnya tetapi hanya sekadar menyebutnya. Ia adalah Form.
Form umumnya digunakan untuk menangkap input dari user dalam jumlah banyak sekaligus. Bisa ditebak dari namanya pasti bentuk form akan mirip seperti formulir.
Lengkap, bukan? Ada field yang bisa diisi dan ada juga tombol bernama "Submit Data" ketika kita sudah selesai mengisi data pada form. Sama halnya dengan elemen HTML pada umumnya, terdapat beberapa event yang dihasilkan oleh form yang akan kita terapkan pada praktik. Untuk penjabarannya, perhatikan tabel di bawah ini:
Nama Event | Penjelasan |
---|---|
onsubmit | Event ini akan terjadi ketika kita menekan tombol submit milik sebuah form |
oninput | Event ini akan terjadi jika kita memberikan input melalui field. |
onchange | Event ini akan terjadi jika kita sudah selesai memberikan input melalui field. Bisa juga diaplikasikan ke elemen select (dropdown menu). |
oncopy | Event ini akan terjadi jika kita menyalin (copy) isi dari sebuah elemen. |
onpaste | Event ini akan terjadi jika kita menempel (paste) isi dari hasil salin (copy) pada sebuah teks. |
onfocus | Event ini akan terjadi jika sebuah elemen pada form dipilih untuk dilakukan proses input. |
onblur | Event ini akan terjadi jika sebuah elemen pada form tidak dipilih lagi untuk dilakukan proses input. |
Sekali lagi, Anda tidak perlu menghafal semua event di atas secara detail. Karena kita akan membahasnya secara rinci serta mempraktikkannya pada materi berikutnya yakni “Input Event”. Sudah siap menerapkan form pada halaman web Anda? Yuk, kita lanjut.
Form Event
Saat selesai mengisi form pada sebuah halaman web, umumnya Anda akan mengarahkan cursor untuk submit semua data yang sudah terisi, bukan? Biasanya tombol tersebut memiliki caption seperti “Submit”, “Save”, atau semisalnya. Tombol tersebut biasanya berfungsi untuk mengirim data-data yang telah diinputkan oleh user pada form kepada proses lain, misalnya seperti mengirim data tersebut ke server untuk memperbarui data profil Anda.
Tapi tahukah Anda bahwa tombol tersebut unik? Unik dalam arti tombol pada form tidak dibuat melalui tag <button> (secara default bertipe "button") yang selama ini kita gunakan, melainkan sebuah tag khusus yakni <input> yang memiliki atribut type bernilai “submit”. Selain menggunakan tag <input>, kita juga bisa menggunakan tag <button> yang memiliki atribut type bernilai "submit", bukan "button".
Mungkin Anda berpikir bahwa untuk mengendalikan ter-submitnya form ke server perlu memberikan event submit pada tombol submit. Tentu tidak, kita akan memberikannya pada elemen <form> (jika menggunakan method addEventListener).
Event onSubmit
Baik, cukup dengan teori, bagaimana jika lanjut melalui praktik saja? Pertama mari kita buat sebuah berkas HTML.
<!DOCTYPE html> <html> <head> <title>Form World</title> <style> .contents { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding : 15px; } .form-element { margin: 8px; text-align: left; } </style> </head> <body> <div class="contents"> <h2 align="center">Isi data diri</h2> <div class="formContent"> <form id="formDataDiri"> <div class="form-element"> <label for="inputNama">Nama:</label><br> <input type="text" id="inputNama" name="nama" placeholder="Nama Anda" required><br> </div> <div class="form-element"> <label for="inputDomisili">Domisili:</label><br> <input type="text" id="inputDomisili" name="domisili" placeholder="Domisili Anda" required><br> </div> <div class="form-element"> <input type="submit" value="Submit Data"> </div> </form> </div> <h3 id="messageAfterSubmit"></h3> </div> <script> // masukkan kodemu di sini </script> </body> </html>
Maka tampilan web kita akan berbentuk seperti ini:
Kita akan menambahkan sebuah fitur unik, yakni munculnya sebuah kalimat di bawah tombol button. Sudah siap?
Kita hanya perlu menambahkan event listener pada elemen form dengan menambahkan kode pada bagian <script>.
const submitAction = document.getElementById('formDataDiri'); submitAction.addEventListener('submit', function (event) { const inputNama = document.getElementById('inputNama').value; const inputDomisili = document.getElementById('inputDomisili').value; const hiddenMessage = 'Halo ' + inputNama + ', bagaimana cuacanya di ' + inputDomisili + '?'; document.getElementById('messageAfterSubmit').innerText = hiddenMessage; event.preventDefault(); });
Penggunaan object event (terkecuali argument pada parameter) telah usang (deprecated). Solusinya, kamu bisa menambahkan parameter event atau e (penamaan tidak paten), yang mana object event akan tersimpan pada argument tersebut, sehingga kita dapat menggunakannya sesuai kebutuhan.
Kode di atas akan mengambil nilai yang sudah di-input oleh user. Caranya adalah memanggil properti value dari masing-masing elemen input pada form. Lalu, input akan dimasukkan ke sebuah string dengan sebuah format khusus yang akan ditampilkan ke layar.
Ada sebuah kode baru yang belum pernah kita bahas yakni event.preventDefault(). Apa fungsi kode tersebut? Ketika kita melakukan proses submit pada form, halaman web akan melakukan proses refresh. Nah, event.preventDefault() akan mencegah proses refresh tersebut.
Sebelum kita jalankan, pastikan halaman web memiliki berkas HTML yang isinya sebagai berikut:
<!DOCTYPE html> <html> <head> <title>Form World</title> <style> .contents { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 2px solid black; padding: 15px; } .form-element { margin: 8px; text-align: left; } </style> </head> <body> <div class="contents"> <h2 align="center"> Isi data diri</h2> <div class="formContent"> <form id="formDataDiri"> <div class="form-element"> <label for="inputNama">Nama:</label><br> <input id="inputNama" type="text" name="nama" placeholder="Nama Anda" required><br> </div> <div class="form-element"> <label for="inputDomisili">Domisili:</label><br> <input id="inputDomisili" type="text" name="domisili" placeholder="Domisili Anda" required><br> </div> <div class="form-element"> <input id="submitButton" type="submit" value="Submit Data"> </div> </form> </div> <h3 id="messageAfterSubmit"></h3> </div> <script> const submitAction = document.getElementById('formDataDiri'); submitAction.addEventListener('submit', function (event) { const inputNama = document.getElementById('inputNama').value; const inputDomisili = document.getElementById('inputDomisili').value; const hiddenMessage = 'Halo ' + inputNama + ', bagaimana cuacanya di ' + inputDomisili + '?'; document.getElementById('messageAfterSubmit').innerText = hiddenMessage; event.preventDefault(); }); </script> </body> </html>
Jika kita menginput nama dan domisili lalu menekan tombol “Submit Data”, akan muncul sebuah teks berupa kalimat sapaan seperti di bawah ini.
Melalui form ini, Anda bisa meminta user memasukkan nilai apa pun yang dibutuhkan dan memprosesnya dalam kode JavaScript untuk menghasilkan fungsionalitas yang lebih beragam berdasarkan input dari user.
Berikutnya kita akan menjelajah event milik atribut input seperti onInput, onChange, onCopy, onPaste, onFocus, dan onBlur.
Input Event
Menyiapkan Halaman Website
Pada materi sebelumnya, kita telah membahas beberapa event untuk elemen <form>. Nah, untuk membuat form yang kaya akan fitur, kita bisa menambahkan event listener untuk setiap elemen input di dalam form. Kita akan mulai dengan event onInput. Setelah itu adalah onFocus, onBlur, onChange, onCopy, dan yang terakhir adalah onPaste.
Sesuai dengan kebiasaan kita pada materi-materi sebelumnya, buat berkas HTML baru terlebih dahulu dan beri nama input-event.html.
<!DOCTYPE html> <html> <head> <title>Form World</title> <style> .contents { border: 2px solid black; padding: 8px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); } .form-element { margin: 8px; text-align: left; } #notifikasiSisaKarakter { visibility: hidden; } </style> </head> <body> <div class="contents"> <h2 align="center"><b>Input Event Form</b></h2> <div class="formContent"> <form id="formDataDiri" autocomplete="off"> <div class="form-element" id="fieldName"> <label for="inputNama">Nama Panggilan:</label><br> <input id="inputNama" type="text" name="nama" placeholder="Nama panggilan Anda" maxlength="15"><br> <label id="notifikasiSisaKarakter">Sisa karakter : <span id="sisaKarakter"></span></label> </div> <div class="form-element" id="fieldCopy"> <label for="inputCopy"><i>Copy</i> tulisan ini:</label><br> <input id="inputCopy" type="text" name="copy" value="Hello World!" readonly><br> </div> <div class="form-element" id="fieldPaste"> <label for="inputPaste"><i>Paste</i> tulisan di sini:</label><br> <input id="inputPaste" type="text" name="paste" placeholder="Paste sesuatu di sini"><br> </div> <div class="form-element" id="fieldCaptcha"> <label for="inputCaptcha">Tulis <i>captcha</i> berikut:</label><br> <img src="https://i.ibb.co/yy59QPB/Captcha.png" alt="Captcha"><br> <input id="inputCaptcha" type="text" name="captcha" placeholder="Tulis captcha di sini"><br> <p>Tekan Enter pada keyboard jika sudah selesai menulis <i>captcha</i></p> </div> <div class="form-element" align="center"> <input id="submitButton" type="submit" value="Submit Data" disabled> </div> </form> </div> </div> <script> document.addEventListener('DOMContentLoaded', function () { const inputMaxLengthOnLoad = document.getElementById('inputNama').maxLength; document.getElementById('sisaKarakter').innerText = inputMaxLengthOnLoad; }); </script> </body> </html>
Pada HTML Element yang memiliki atribut align berfungsi untuk memosisikan seluruh child element pada parent element-nya. Namun, penggunaan atribut ini sudah usang (deprecated) sehingga penggunaannya sudah tidak di rekomendasikan kembali. Solusinya adalah menuliskan aturan styling menggunakan CSS.
Berkas HTML di atas akan memiliki tampilan awal sebagai berikut.
Event onInput
Event onInput akan dijalankan setiap kali kita menulis atau menghapus apa pun pada sebuah field input yang memiliki event listener tersebut. Berkas HTML yang telah ditunjukkan di materi sebelumnya, field untuk mengisi nama panggilan (tag input dengan id inputNama) memiliki batas 15 karakter. Kita ingin membuat sebuah event handler, yang mana ketika menulis nama, akan ditampilkan sisa karakter yang dapat dituliskan oleh user.
Kita akan menggunakan event onInput untuk memeriksa setiap kali menulis atau menghapus karakter. Ingat ya, karena nanti kita menggunakan method addEventListener(), maka versi string event onInput untuk dimasukkan ke parameter pertama method tersebut adalah “input”.
Untuk mengimplementasi fitur tersebut, kita harus menambahkan event listener pada input yang memiliki id dengan nilai “inputNama” dan memperbarui teks setiap kali kita menulis atau menghapus karakter baru.
Tambahkan kode berikut ke dalam elemen <script>.
<script> document.addEventListener('DOMContentLoaded', function () { const inputMaxLengthOnLoad = document.getElementById('inputNama').maxLength; document.getElementById('sisaKarakter').innerText = inputMaxLengthOnLoad; document.getElementById('inputNama').addEventListener('input', function () { const jumlahKarakterDiketik = document.getElementById('inputNama').value.length; const jumlahKarakterMaksimal = document.getElementById('inputNama').maxLength; console.log('jumlahKarakterDiketik: ', jumlahKarakterDiketik); console.log('jumlahKarakterMaksimal: ', jumlahKarakterMaksimal); const sisaKarakterUpdate = jumlahKarakterMaksimal - jumlahKarakterDiketik; document.getElementById('sisaKarakter').innerText = sisaKarakterUpdate.toString(); if (sisaKarakterUpdate === 0) { document.getElementById('sisaKarakter').innerText = 'Batas maksimal tercapai!'; } else if (sisaKarakterUpdate <= 5) { document.getElementById('notifikasiSisaKarakter').style.color = 'red'; } else { document.getElementById('notifikasiSisaKarakter').style.color = 'black'; } }); }); </script>
Kode di atas akan memeriksa jumlah karakter yang diperbolehkan dan didapatkan dari pengurangan atribut maxLength pada elemen <input> dengan jumlah karakter pada atribut value milik elemen <input> itu sendiri.
Jumlah karakter akan terus diperbarui selama kita mengetik atau menghapus karakter baru. Kondisi if dengan else if dibuat sekadar untuk memberikan variasi terhadap pesan jumlah karakter sisa yang ingin ditampilkan. Ketika kita menjalankan berkas HTML yang telah ditambahkan kode di atas, hasilnya akan terlihat seperti berikut.
Kita bisa melihat secara langsung apakah nama panggilan yang diinputkan akan muat atau tidak. Lalu, bagaimana jika kita ingin pesan tersebut muncul hanya ketika user berada di elemen input atau sedang fokus pada field input tersebut untuk menulis nama panggilan? Hal tersebut akan kita pelajari dan praktikkan melalui materi event onFocus dan onBlur.
Event onFocus
Event onFocus akan dijalankan ketika melakukan klik di sebuah elemen input. Kita akan mencoba untuk menampilkan tulisan berupa notifikasi jumlah karakter yang masih diperbolehkan. Untuk dapat melakukan hal tersebut, kita harus menambahkan sebuah event handler pada elemen input yang menerima penulisan nama panggilan untuk event onFocus.
Pada elemen <script> pada berkas HTML, tambahkan kode berikut ini:
<script> document.addEventListener('DOMContentLoaded', function () { const inputMaxLengthOnLoad = document.getElementById('inputNama').maxLength; document.getElementById('sisaKarakter').innerText = inputMaxLengthOnLoad; document.getElementById('inputNama').addEventListener('input', function () { const jumlahKarakterDiketik = document.getElementById('inputNama').value.length; const jumlahKarakterMaksimal = document.getElementById('inputNama').maxLength; console.log('jumlahKarakterDiketik: ', jumlahKarakterDiketik); console.log('jumlahKarakterMaksimal: ', jumlahKarakterMaksimal); const sisaKarakterUpdate = jumlahKarakterMaksimal - jumlahKarakterDiketik; document.getElementById('sisaKarakter').innerText = sisaKarakterUpdate.toString(); if (sisaKarakterUpdate === 0) { document.getElementById('sisaKarakter').innerText = 'Batas maksimal tercapai!'; } else if (sisaKarakterUpdate <= 5) { document.getElementById('notifikasiSisaKarakter').style.color = 'red'; } else { document.getElementById('notifikasiSisaKarakter').style.color = 'black'; } }); document.getElementById('inputNama').addEventListener('focus', function () { console.log('inputNama: focus'); document.getElementById('notifikasiSisaKarakter').style.visibility = 'visible'; }); }); </script>
Kode di atas akan menyembunyikan pesan sisa karakter ketika kita mulai melakukan proses penulisan (fokus) pada elemen <input id="inputNama">.
Mantap, bukan? Walau form kita sudah bekerja sesuai dengan permintaan, tapi masih ada kejanggalan. Kejanggalannya terjadi ketika mengisi data pada elemen <input> lain atau tidak lagi fokus pada elemen tersebut, pesan sisa karakter tetap tampil dan tidak hilang. Hal tersebut dapat kita atasi dengan menambahkan event handler ketika event onBlur terjadi untuk elemen <input> tersebut.
Event onBlur
Event onBlur akan dijalankan ketika pada kondisi yang terbalik dengan event onFocus, yakni jika kita “pergi” dari elemen yang memiliki event handler untuk event onFocus. Apa maksud dari “pergi”? Maksudnya adalah kita tidak lagi berinteraksi secara langsung dengan elemen tersebut, seperti kita telah melakukan klik pada elemen lain.
Dalam elemen <script> dalam berkas HTML, tambahkan kode (sebuah event listener lagi) pada elemen <input> berikut untuk menerima input nama panggilan:
<script> document.addEventListener('DOMContentLoaded', function () { const inputMaxLengthOnLoad = document.getElementById('inputNama').maxLength; document.getElementById('sisaKarakter').innerText = inputMaxLengthOnLoad; document.getElementById('inputNama').addEventListener('input', function () { const jumlahKarakterDiketik = document.getElementById('inputNama').value.length; const jumlahKarakterMaksimal = document.getElementById('inputNama').maxLength; console.log('jumlahKarakterDiketik: ', jumlahKarakterDiketik); console.log('jumlahKarakterMaksimal: ', jumlahKarakterMaksimal); const sisaKarakterUpdate = jumlahKarakterMaksimal - jumlahKarakterDiketik; document.getElementById('sisaKarakter').innerText = sisaKarakterUpdate.toString(); if (sisaKarakterUpdate === 0) { document.getElementById('sisaKarakter').innerText = 'Batas maksimal tercapai!'; } else if (sisaKarakterUpdate <= 5) { document.getElementById('notifikasiSisaKarakter').style.color = 'red'; } else { document.getElementById('notifikasiSisaKarakter').style.color = 'black'; } }); document.getElementById('inputNama').addEventListener('focus', function () { console.log('inputNama: focus'); document.getElementById('notifikasiSisaKarakter').style.visibility = 'visible'; }); document.getElementById('inputNama').addEventListener('blur', function () { console.log('inputNama: blur'); document.getElementById('notifikasiSisaKarakter').style.visibility = 'hidden'; }); }); </script>
Kode yang ditambahkan tersebut hanyalah melakukan kebalikan dari event handler untuk event onFocus yang kita terapkan sebelumnya. Kode tersebut akan “menyembunyikan” kembali pesan notifikasi jumlah sisa karakter yang diperbolehkan. Proses tersebut terjadi ketika kita klik elemen lain alias elemen <input> yang membuat nama panggilan sudah tidak menjadi fokus utama lagi.
Akhirnya, bagian form yang meminta nama panggilan, sudah memiliki fungsionalitas lengkap yang kita harapkan melalui penerapan event handler dan event listener untuk semua event yang sudah ditentukan. Berikutnya, kita akan menerapkan fitur pada bagian form lain yakni bagian captcha terlebih dahulu. Apa yang ingin kita tambahkan? Simak di materi berikutnya ya!
Event onChange
Event onChange memiliki perilaku yang sama dengan onInput, yakni akan terjadi jika terdeteksi adanya perubahan nilai yang dimasukkan. Perbedaannya terletak pada “kapan” event ini terjadi.
Pada onInput, event akan terjadi setiap kali nilai yang diinput mengalami perubahan (contohnya penambahan atau pengurangan karakter). Sedangkan pada onChange, event akan terjadi setelah elemen tersebut tidak menjadi fokus lagi alias kita tidak berinteraksi dengannya lagi lalu akan diperiksa apakah ada perubahan atau tidak. Perbedaan keduanya akan tampak saat kita mempraktikkannya.
Fitur yang ingin kita tambahkan adalah jika kita menulis captcha dengan benar, tombol “Submit Data” bisa ditekan. Bagaimana cara menambahkan event handler onChange pada elemen <input> untuk captcha? Simak uraiannya di bawah ini:
Tambahkan kode berikut ini.
document.getElementById('inputCaptcha').addEventListener('change', function () { console.log('inputChaptcha: change'); const inputCaptcha = document.getElementById('inputCaptcha').value; const submitButtonStatus = document.getElementById('submitButton'); if (inputCaptcha === 'PRNU') { submitButtonStatus.removeAttribute('disabled'); } else { submitButtonStatus.setAttribute('disabled', ''); } });
Kode di atas akan memeriksa apakah kita memasukkan teks yang sesuai dengan captcha-nya. Jika sesuai, tombol “Submit Data” menjadi aktif. Namun, perlu diperhatikan bahwa melalui event onChange, kita harus lebih dulu “mengalihkan” fokus ke elemen lain atau bisa juga dicapai dengan hanya menekan tombol “Enter” pada keyboard. Sehingga, walaupun penulisan kita sudah sesuai dengan yang ada di captcha, event onChange tidak akan terjadi sampai kita menekan tombol “Enter” atau “mengalihkan” fokus ke elemen lain.
Dari preview di atas kita bisa tahu walaupun sudah menulis konten yang benar sesuai dengan captcha, tombol tidak kunjung bisa ditekan sebelum “mengalihkan” fokus ke elemen lain. Coba kita ubah nilai input captcha ke nilai yang salah. Alhasil, tombol tetap bisa ditekan meskipun tulisan captcha yang dimasukkan tidak sesuai.
Meskipun demikian, tombol masih bisa ditekan ketika input tidak sesuai captcha selama kita langsung menekan tombolnya. Untuk memperbaiki kesalahan, tambahkan kode berikut di akhir elemen <script>:
document.getElementById('formDataDiri').addEventListener('submit', function (event) { const inputCaptcha = document.getElementById('inputCaptcha').value; if (inputCaptcha === 'PRNU') { alert('Selamat! Captcha Anda lolos :D'); } else { alert('Captcha Anda belum tepat :('); document.getElementById('submitButton').setAttribute('disabled', ''); } event.preventDefault(); });
Silakan jalankan dan masukkan captcha kembali. Sekarang kita sudah tidak bisa men-submit data ketika captcha yang dimasukkan salah. Bug berhasil dihilangkan!
Event onCopy
Event onCopy tergolong dalam kelompok clipboard events. Event ini terjadi jika kita melakukan operasi pada clipboard seperti copy, cut, dan paste. Kita hanya akan membahas dua saja, yaitu event onCopy sebagai operasi copy dan event onPaste sebagai operasi paste. Pertama kita akan menggunakan onCopy terlebih dahulu.
Pada berkas HTML di atas, kita sudah memiliki bagian form yang dihiasi dengan kata kunci “copy”. Tugas kita kali ini adalah menambahkan event listener untuk event onCopy. Sedangkan fungsi event handler-nya hanyalah memunculkan sebuah dialog box alert yang berisi pesan “Anda telah men-copy sesuatu...”.
Untuk menambah fitur tersebut, maka kita hanya perlu menambahkan kode berikut ke dalam elemen <script>.
document.getElementById('inputCopy').addEventListener('copy', function () { alert('Anda telah men-copy sesuatu...'); });
Melalui kode di atas, kita telah membuat berkas HTML yang memunculkan alert dialog box ketika menyalin tulisan dari elemen <input> tersebut. Tampilan ketika dijalankan seperti berikut.
Event onPaste
Event onPaste tergolong dalam kelompok clipboard events seperti yang kita bahas sebelumnya. Event ini akan terjadi ketika melakukan operasi paste pada elemen yang sudah kita beri event listener untuk event onPaste.
Pada berkas HTML di atas, kita juga sudah memiliki bagian form yang dihiasi dengan kata kunci “paste”. Tugas kali ini mirip dengan apa yang telah kita lakukan pada event onCopy. Kita hanya membuat fungsi event handler untuk memunculkan sebuah dialog box alert yang berisi pesan “Anda telah mem-paste sebuah teks...”.
Untuk menambah fitur tersebut, tambahkan kode berikut ke dalam elemen <script>.
document.getElementById('inputPaste').addEventListener('paste', function () { alert('Anda telah mem-paste sebuah teks...'); });
Melalui kode di atas, kita telah membuat berkas HTML memunculkan alert dialog box ketika mem-paste tulisan dari elemen <input>. Jika kita jalankan, tampilannya terlihat seperti berikut.
Hasil Akhir
Selamat! Setelah melalui modifikasi yang cukup banyak pada elemen <script>, kini semua fungsionalitas yang kita inginkan sudah “tertanam” pada halaman web. Sehingga hasil akhir dari berkas input-event.html akan terlihat seperti di bawah ini:
<!DOCTYPE html> <html> <head> <title>Form World</title> <style> .contents { padding: 8px; border: 2px solid black; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); } .form-element { margin: 8px; text-align: left; } #notifikasiSisaKarakter { visibility: hidden; } </style> </head> <body> <div class="contents"> <h2 align="center"><b>Input Event Form</b></h2> <div class="formContent"> <form id="formDataDiri" autocomplete="off"> <div class="form-element" id="fieldName"> <label for="inputNama">Nama Panggilan:</label><br> <input id="inputNama" type="text" name="nama" placeholder="Nama panggilan Anda" maxlength="15"><br> <span id="notifikasiSisaKarakter">Sisa karakter : <span id="sisaKarakter"></span></span> </div> <div class="form-element" id="fieldCopy"> <label for="inputCopy"><i>Copy</i> tulisan ini:</label><br> <input id="inputCopy" type="text" name="copy" value="Hello World!" readonly><br> </div> <div class="form-element" id="fieldPaste"> <label for="inputPaste"><i>Paste</i> tulisan di sini:</label><br> <input id="inputPaste" type="text" name="paste" placeholder="Paste sesuatu di sini"><br> </div> <div class="form-element" id="fieldCaptcha"> <label for="inputCaptcha">Tulis <i>captcha</i> berikut:</label><br> <img src="https://i.ibb.co/yy59QPB/Captcha.png" alt="Captcha"><br> <input id="inputCaptcha" type="text" name="captcha" placeholder="Tulis captcha di sini"><br> <p>Tekan Enter pada keyboard jika sudah selesai menulis <i>captcha</i></p> </div> <div class="form-element" align="center"> <input id="submitButton" type="submit" value="Submit Data" disabled> </div> </form> </div> </div> <script> document.addEventListener('DOMContentLoaded', function () { const inputMaxLengthOnLoad = document.getElementById('inputNama').maxLength; document.getElementById('sisaKarakter').innerText = inputMaxLengthOnLoad; document.getElementById('inputNama').addEventListener('input', function () { const jumlahKarakterDiketik = document.getElementById('inputNama').value.length; const jumlahKarakterMaksimal = document.getElementById('inputNama').maxLength; console.log('jumlahKarakterDiketik: ', jumlahKarakterDiketik); console.log('jumlahKarakterMaksimal: ', jumlahKarakterMaksimal); const sisaKarakterUpdate = jumlahKarakterMaksimal - jumlahKarakterDiketik; document.getElementById('sisaKarakter').innerText = sisaKarakterUpdate.toString(); if (sisaKarakterUpdate === 0) { document.getElementById('sisaKarakter').innerText = 'Batas maksimal tercapai!'; } else if (sisaKarakterUpdate <= 5) { document.getElementById('notifikasiSisaKarakter').style.color = 'red'; } else { document.getElementById('notifikasiSisaKarakter').style.color = 'black'; } }); document.getElementById('inputNama').addEventListener('focus', function () { console.log('inputNama: focus'); document.getElementById('notifikasiSisaKarakter').style.visibility = 'visible'; }); document.getElementById('inputNama').addEventListener('blur', function () { console.log('inputNama: blur'); document.getElementById('notifikasiSisaKarakter').style.visibility = 'hidden'; }); document.getElementById('inputCaptcha').addEventListener('change', function () { console.log('inputChaptcha: change'); const inputCaptcha = document.getElementById('inputCaptcha').value; const submitButtonStatus = document.getElementById('submitButton'); if (inputCaptcha === 'PRNU') { submitButtonStatus.removeAttribute('disabled'); } else { submitButtonStatus.setAttribute('disabled', ''); } }); document.getElementById('formDataDiri').addEventListener('submit', function (event) { const inputCaptcha = document.getElementById('inputCaptcha').value; if (inputCaptcha === 'PRNU') { alert('Selamat! Captcha Anda lolos :D'); } else { alert('Captcha Anda belum tepat :('); document.getElementById('submitButton').setAttribute('disabled', ''); } event.preventDefault(); }); document.getElementById('inputCopy').addEventListener('copy', function () { alert('Anda telah men-copy sesuatu...'); }); document.getElementById('inputPaste').addEventListener('paste', function () { alert('Anda telah mem-paste sebuah teks...'); }); }); </script> </body> </html>
Silakan kamu jalankan kembali hasil akhir latihan kita dan menguji semua fungsionalitasnya.
Sebelumnya : Pengenalan Document Object Model | Selanjutnya : Membuat Aplikasi Todo Apps |
0 Komentar