15 Desember 2021

Pengenalan ke peristiwa peramban (_browser events_)

Sebuah Peristiwa adalah penanda bahwa sesuatu telah terjadi. Semua DOM nodes menghasilkan sebuah penanda (tapi peristiwa tidak hanya terbatas pada DOM).

Berikut ini daftar peristiwa DOM yang paling berguna:

Peristiwa mouse (Mouse events):

  • click – pada saat mouse mengklik sebuah elemen (perangkat layar sentuh menghasilkan peristiwa ini pada saat ditekan)
  • contextmenu – pada saat mouse mengklik kanan sebuah elemen.
  • mouseover / mouseout – pada saat kursor mouse menghampiri / meninggalkan sebuah elemen.
  • mousedown / mouseup – pada saat tombol mouse button ditekan / dilepaskan diatas sebuah elemen.
  • mousemove – pada saat mouse bergerak.

Peristiwa papan ketik (Keyboard events):

  • keydown dan keyup – pada saat tombol papan ketik ditekan dan dilepaskan.

Peristiwa Elemen form (Form element events):

  • submit – pada saat pengunjung memasukan sebuah <form>.
  • focus – pada saat pengunjung menekan/mengfokus pada sebuah elemen, contoh pada sebuah <input>.

Peristiwa dokumen (Document events):

  • DOMContentLoaded – pada saat HTML telah dimuat dan diproses, DOM telah sepenuhnya dibuat.

Peristiwa CSS (CSS events):

  • transitionend – pada saat animasi CSS selesai.

Masih banyak lagi peristiwa lain. Kita akan membahas lebih detail tentang peristiwa tertentu pada bab selanjutnya.

Penangan peristiwa (Event handlers)

Untuk menanggapi sebuah perristiwa kita dapat membuat penangan – sebuah fungsi yang akan dijalankan pada saat peristiwa itu terjadi.

penangan adalah sebuah cara untuk menjalankan kode Javascript pada saat pengguna melakukan sesuatu.

Ada banyak cara untuk membuat sebuah handler. Mari kita pelajari, dimulai dari yang paling sederhana.

Atribut HTML (HTML-attribute)

Sebuah penangan bisa di atur pada HTML dengan menggunakan atribute on<event>.

Contohnya, untuk mengatur sebuah penangan klik untuk input, kita bisa gunakan onclick, seperti ini:

<input value="Klik saya" onclick="alert('Klik!')" type="button">

Pada klik mouse, kode didalam onclick dijalankan.

Harap di catat bahwa didalam onclick kita gunakan tanda kutipan tunggal (single quotes), karena atribute itu sendiri menggunakan tanda kutip ganda (double quotes). Jika lupa bahwa kode tersebut didalam atribut dan menggunakan tanda kutip ganda (double quotes), seperti ini: onclick="alert("Klik!")", maka itu tidak akan bekerja dengan benar.

Sebuah atribute-HTML bukan tempat yang cocok untuk menulis banyak kode, jadi kita buat sebuah fungsi Javascript dan memanggilnya disana.

Sebuah kilk menjalankan sebuah fungsi hitungKelinci():

<script>
  function hitungKelinci() {
    for(let i=1; i<=3; i++) {
      alert("Kelinci nomor " + i);
    }
  }
</script>

<input type="button" onclick="hitungKelinci()" value="Hitung Kelinci!">

Seperti yang kita ketahui, atribut HTML tidak case-sensitive, jadi ONCLICK, onClick dan onCLICK bisa digunakan… Tapi biasanya atribut menggunakan huruf kecil: onclick.

Properti DOM (DOM property)

Sebuah penangan bisa di atur menggunakan properti DOMon<event>.

Contohnya, elem.onclick:

<input id="elem" type="button" value="Klik saya">
<script>
  elem.onclick = function() {
    alert('Terima Kasih');
  };
</script>

Jika penangan di atur menggunakan atribut-HTML maka peramban membaca, membuat sebuah fungsi baru dari konten atribute dan menulisnya pada properti DOM.

Jadi cara ini sebenarnya sama dengan yang sebelumnya.

Kedua kode ini memiliki cara kerja yang sama:

  1. Hanya HTML:

    <input type="button" onclick="alert('Klik!')" value="Tombol">
  2. HTML + JS:

    <input type="button" id="button" value="Tombol">
    <script>
      button.onclick = function() {
        alert('Klik!');
      };
    </script>

Pada contoh pertama, atribut HTML digunakan untuk menginisialisasikan tombol.onclick, sedangkan pada contoh kedua – script, dan hanya itu perbedaanya.

Karena hanya ada satu properti onclick, kita tidak bisa mengatur lebih dari satu penangan peristiwa.

Pada contoh dibawah menambah sebuah penangan menggunakan Javascript akan menimpa penangan yang sudah ada:

<input type="button" id="elem" onclick="alert('Sebelum')" value="Klik saya">
<script>
  elem.onclick = function() { // menimpa penangan yang sudah ada
    alert('Sesudah'); // hanya ini yang akan ditunjukan
  };
</script>

Untuk menghapus sebuah penangan – atur elem.onclick = null

Mengakses elemen: this

nilai dari this didalam penangan adalah elemen tersebut. Elemen yang dimana penangan itu berada.

Pada kode dibawah button menampilkan kontennya dengan menggunakan this.innerHTML:

<button onclick="alert(this.innerHTML)">Klik saya</button>

Kemungkinan kesalahan

Jika kamu mulai bekerja dengan menggunakan peristiwa – harap perhatikan beberapa detail.

Kita bisa mengatur sebuah fungsi yang telah ada sebagai penangan:

function ucapkanTerimaKasih() {
  alert('Terima Kasih!');
}

elem.onclick = ucapkanTerimaKasih;

Tetapi berhati-hatilah: fungsi harus di atur sebagai ucapkanTerimaKasih, bukan ucapkanTerimaKasih().

// benar
button.onclick = ucapkanTerimaKasih;

// salah
button.onclick = ucapkanTerimaKasih();

Jika kita tambahkan tanda kurung, maka ucapkanTerimaKasih() menjadi proses pemanggilan fungsi. Jadi baris terakhir akan mengambil hasil dari pengeksekusian fungsi, yang merupakan tidak terdefinisi (undefined — karena fungsi tidak mengembalikan apapun), dan mengatur nilai itu ke peristiwa onclick. Maka peristiwa tersebut tidak akan menjalankan apapun.

…Namun, jika kita menambahkan secara langsung ke HTML, maka kita harus menambahkan tanda kurung:

<input type="button" id="button" onclick="ucapkanTerimaKasih()">

Perbedaannya mudah untuk di jelaskan. Pada saat peramban membaca atribute, peramban akan membuat fungsi penangan yang didalamnya terdapat konten dari atribut tersebut.

Jadi HTML akan menghasilkan properti ini:

button.onclick = function() {
  ucapkanTerimaKasih(); // <-- konten dari atribut akan ditambahkan kesini
};

Jangan gunakna setAttribute untuk membuat penangan.

Penggunaan tersebut tidak akan berjalan:

// sebuah klik pada <body> akan menghasilakn eror
// karena atribute akan selalu menjadi teks (string), dimana fungsi akan menjadi teks (string)
document.body.setAttribute('onclick', function() { alert(1) });

Properti DOM mementingkan kesamaan huruf.

Atur sebuah penangan ke elem.onclick, bukan elem.ONCLICK, karena properti DOM mementingkan kesamaan huruf (case-sensitive).

tambahkanPendengarPeristiwa (addEventListener)

Salah satu masalah mendasar pada cara mengatur pengedali sebelumnya – kita tidak bisa mengatur beberapa penangan pada sebuah peristiwa.

Mari kata, sebuah bagian pada koded kita ingin menyoroti sebuah tombol pada saat diklik, dan satu lagi ingin menunjukan seubah pesan pada proses pengklikan tersebut.

Kita ingin mengatur dua penangan peristiwa untuk hal tersebut. Tapi properti DOM yang baru akan menimpa properti DOM yang telah ada.

input.onclick = function() { alert(1); }
// ...
input.onclick = function() { alert(2); } // menganti pengedali yang lama

Pengembang dari standar situs web paham sejak lama, dan menyarankan cara alternatif untuk mengelola penangan menggunakan metode khusus addEventListener dan removeEventListener. Kedua hal tersebut tidak memiliki permasalahan seperti itu.

Sintaks (syntax) untuk menambahkan sebuah penangan:

element.addEventListener(event, handler, [options]);
peristiwa/event
nama Peristiwa, contoh "click".
penangan/handler
penangan fungsi.
pilihan/options
sebuah objek pilihan tambahan dengan properti:
  • once: jika true, maka pendengar akan secara otomatis dihapus setelah terpicu.
  • capture: fase dimana untuk menangani peristiwa, akan di bahas lebih lanjut pada bab Menggelembung (_bubbling_) dan menangkap (_capturing_). untuk alasan sejarah, options bisa juga diatur false/true, sama halnya dengan {capture: false/true}.
  • passive: jika true, maka penangan tidak akan memanggil preventDefault(), kita akan membahas lebih lanjut pada bab _Browser default actions_.

Untuk menghapus penangan, gunakan removeEventListener:

element.removeEventListener(event, handler, [options]);
Penghapusan membutuhkan fungsi yang sama

Untuk menghapus sebuah penangan kita melewatkan fungsi yang sama dengan yang kita atur.

Ini tidak akan berfungsi:

elem.addEventListener( "click" , () => alert('Terima Kasih!'));
// ....
elem.removeEventListener( "click", () => alert('Terima Kasih!'));

Pengedali tidak akan dihapus, karena removeEventListener mendapat sebuah fungsi lain – dengan kode yang sama, tetapi hal tersebut tidak penting, karena itu merupakan objek fungsi yang berbeda.

Inilah cara yang benar:

function handler() {
  alert( 'Terima Kasih!' );
}

input.addEventListener("click", handler);
// ....
input.removeEventListener("click", handler);

Harap dicatat – Jika kita tidak menyimpan fungsi tersebut kedalam variable, maka kita tidak bisa menghapusnya. Tidak ada cara untuk “membaca kembali” penangan yang di atur pada addEventListener.

Beberapa pemanggilan ke addEventListener mengijinkan untuk menambahkan beberapa penangan, seperti ini:

<input id="elem" type="button" value="Klik saya"/>

<script>
  function penangan1() {
    alert('Terima Kasih!');
  };

  function penangan2() {
    alert('Terima Kasih lagi!');
  }

  elem.onclick = () => alert("Halo");
  elem.addEventListener("click", penangan1); // Terima Kasih!
  elem.addEventListener("click", penangan2); // Terima Kasih lagi!
</script>

Seperti yang bisa kita lihat pada contoh di atas, kita bisa mengatur kedua penangan menggunakan properti DOM dan addEventListener. Tapi pada umumnya kita hanya akan menggunakan salah satu.

Untuk beberapa peristiwa, penangan bekerja hanya dengan addEventListener

Ada beberapa peristiwa yang tidak dapat di atur menggunakan properti DOM. hanya dengan addEventListener.

Contohnya, peristiwa DOMContentLoaded, yang akan terpicu pada saat dokumen telah berhasil di dimuat dan dibuat.

// tidak akan perna berjalan
document.onDOMContentLoaded = function() {
  alert("DOM dibuat");
};
// akan berjalan dengan cara ini
document.addEventListener("DOMContentLoaded", function() {
  alert("DOM dibuat");
});

Jadi addEventListener lebih universal. Walaupun, aturan semacam itu merupakan sebuah pengecualian daripada aturan.

Objek peristiwa (Event object)

Untuk menangani peristiwa secara benar sebuah peristiwa kita mau tahu lebih tentang apa yang terjadi. Tidak hanya sebuah “klik” atau sebuah “penekanan tombol”, tapi apa koordinat pointer? tombol mana yang di tekan? dan seterusnya.

Pada saat sebuah peristiwa terjadi, peramban akan membuat objek peristiwa, memasukan detail kedalamnya dan meneruskan peristiwa tersebut ke penangan sebagai sebuah argumen.

Ini merupakan contoh cara untuk mendapat koordinat pointer dari objek peristiwa:

<input type="button" value="Klik saya" id="elem">

<script>
  elem.onclick = function(peristiwa) {
    // tampilkan tipe peristiwa, elemen dan koordinat dari klik
    alert(peristiwa.type + " pada " + peristiwa.currentTarget);
    alert("Koordinat: " + peristiwa.clientX + ":" + peristiwa.clientY);
  };
</script>

Beberapa properti dari objek peristiwa:

peristiwa.type
Tipe peristiwa, disini tipenya "click".
peristiwa.currentTarget
elemen yang ditangani oleh peristiwa. Sama persis dengan this, kecuali jika penangan merupakan fungsi anak panah (arrow function), atau this sudah di atur untuk hal lain, maka kita dapat menggunakan peristiwa.currentTarget untuk mendapati elemen.
peristiwa.clientX / peristiwa.clientY
koordinat kursor relatif pada jendela (window), untuk peristwa pointer.

Masih banyak lagi properti. Banyak yang tergantung pada tipe peristiwa: peristiwa papan ketik memilik satu set properti, peristiwa pointer – memiliki set yang berbeda, kita nanti akan mempelajari mereka pada saat kita mendapati peristiwa lainnya secara detail.

Objek peristiwa juga ada pada penangan HTML

Jika kita mengatur penangan pada HTML, kita bisa juga menggunakan objek peristiwa, seperti ini:

<input type="button" onclick="alert(event.type)" value="Tipe Peristiwa">

Ini terjadi karena pada saat peramban membaca atribut, itu membuat sebuah penangan seperti ini: function(event) {alert(event.type) }. yaitu: argumen pertamanya disebut dengan "event", dan tubuhnya di ambil dari atribut.

Objek penangan: handleEvent

Kita bisa mengatur bukan hanya fungsi, tapi sebuah objek sebagai penangan peristiwa menggunakan addEventListener. Pada saat sebuah peristiwa terjadi, Itu memanggil metode handleEvent.

Contohnya:

<button id="elem">Klik saya</button>

<script>
  let obj = {
    handleEvent(event) {
      alert(event.type + " pada " + event.currentTarget);
    }
  };

  elem.addEventListener('click', obj);
</script>

Seperti yang bisa kita lihat, pada saat addEventListener menerima objek sebagai penangan, itu akan memanggil obj.handleEvent(event) jika sebuah peristiwa terjadi.

Kita juga dapat menggunakan Kelas (class) untuk hal itu:

<button id="elem">Klik saya</button>

<script>
  class Menu {
    handleEvent(event) {
      switch(event.type) {
        case 'mousedown':
          elem.innerHTML = "Tombol mouse ditekan";
          break;
        case 'mouseup':
          elem.innerHTML += "...dan dilepas.";
          break;
      }
    }
  }

  let menu = new Menu();
  elem.addEventListener('mousedown', menu);
  elem.addEventListener('mouseup', menu);
</script>

Disini objek yang sama menanggani kedua peristiwa. Tolong di catat bahwa kita harus secara eksplisit mengatur peristiwa untuk mendengar menggunakan addEventListener. Objek menu hanya dapat menerima mousedown dan mouseup pada contoh diatas, bukan tipe peristiwa lainnya.

Metode handleEvent tidak harus melakukan semua proses secara mandiri. Itu dapat memanggil metode lain yang menanggani peristiwa secara spesifik, seperti ini:

<button id="elem">Klik saya</button>

<script>
  class Menu {
    handleEvent(event) {
      // mousedown -> onMousedown
      let method = 'on' + event.type[0].toUpperCase() + event.type.slice(1);
      this[method](event);
    }

    onMousedown() {
      elem.innerHTML = "Tombol mouse ditekan";
    }

    onMouseup() {
      elem.innerHTML += "...dan dilepas.";
    }
  }

  let menu = new Menu();
  elem.addEventListener('mousedown', menu);
  elem.addEventListener('mouseup', menu);
</script>

Sekarang penangan peristiwa berbeda, dan memudahkan proses pendukungan.

Ringkasan

Ada 3 cara untuk mengatur penangan peristiwa:

  1. Atribute HTML: onclick="..."
  2. Properti DOM: elem.onclick = function.
  3. Metode: elem.addEventListener(event, handler[, phase]) untuk menambahkan, removeEventListener untuk menghapuskan.

Atribute HTML digunakan untuk kasus tertentu, karena Javascript ditengah tag HTML akan kelihatan aneh. Dan juga akan sulit untuk menulis banyak kode di dalam tag HTML.

Properti DOM boleh digunakan, tapi kita tidak dapat mengatur lebih dari 1 penangan untuk peristiwa tertentu. Namun tidak sering kita membutuhkan lebih dari 2 penangan.

Cara terakhir lebih fleksible, tapi itu juga merupakan cara terpanjang untuk menulis. Ada beberapa peristiwa yang hanya akan bisa digunakan pada cara ini, seperti misalnya transitionend dan DOMContentLoaded (akan di bahas). Dan juga objek dapat digunakan sebagai penangan pada addEventListener. Pada kasus ini metode handleEvent akan dipanggil pada saat peristiwa terjadi.

Tidak penting bagaimana kamu mengatur penangan – itu akan mendapat sebuah objek peristiwa sebagai argumen pertama. Objek itu memiliki detail tentang apa yang terjadi.

Kita akan mempelajari lebih lanjut tentang peristiwa secara umum dan perbedaan tipe peristiwa di bab selanjutnya.

Tugas

pentingnya: 5

Tambah Javascript ke button untuk membuat <div id="text"> hilang pada saat di klik.

demo:

Buka sandbox untuk tugas tersebut.

pentingnya: 5

Buat sebuah tombol yang menyembunyikan dirinya sendiri pada saat di klik.

Seperti ini:

Bisa gunakan this pada penangan (handler) untuk mereferensi “elemen itu sendiri”:

<input type="button" onclick="this.hidden=true" value="Klik untuk menyembunyikan">
pentingnya: 5

Ada sebuah tombol pada variable. Tidak ada pengedali di tombol tersebut.

Manakah penangan yang dijalankan pada saat klik pada kode berikut ini? Manakah alert yang akan ditunjukan?

button.addEventListener("click", () => alert("1"));

button.removeEventListener("click", () => alert("1"));

button.onclick = () => alert(2);

Jawabannya: 1 dan 2.

penangan pertama dijalankan, karena tidak di hapuskan oleh removeEventListener. Untuk menghapuskan penangan kita harus meneruskan secara tepat fungsi yang telah di atur. Dan pada kode sebuah fungsi baru di teruskan, terlihat sama, tapi berbeda fungsi.

Untuk menghapuskan objek fungsi, kita harus menyimpan refensi ke fungsi tersebut, seperti ini:

function handler() {
  alert(1);
}

button.addEventListener("click", handler);
button.removeEventListener("click", handler);

penangan button.onclick bekerja secara sendiri dan sebagai tambahan untuk addEvenetListener.

pentingnya: 5

Pindahkan bola ke seberang lapangan pada saat di klik. Seperti ini:

Syarat-Syarat:

  • Pusat bola harus berada tepat dibawah pointer pada saat di klik (jika memungkinkan tanpa melintasi ujung lapangan).
  • Animasi CSS jika memungkinkan.
  • Bola tidak boleh melintasi batas lapangan.
  • Saat halaman di digulir, tidak ada yang rusak.

Tambahan:

  • Kode harus juga bekerja dengan bola yang berbeda dan berbagai ukuran lapangan, tidak hanya pada ukuran tertentu.
  • Gunakan properti event.clientX/event.clientY untuk koordinat klik.

Buka sandbox untuk tugas tersebut.

Pertama kita perlu memilih metode untuk memposisikan bola.

Kita tidak dapat menggunakan position:fixed untuk itu, karena pada saat halaman digulir bola akan berpindah dari lapangan.

Jadi kita sebaiknya menggunakan position:absolute dan, untuk membuat posisinya benar-benar tepat, buat lapangan(field) itu sendiri diposisikan.

Kemudian bola akan diposisikan relatif terhadap lapangan(field):

#field {
  width: 200px;
  height: 150px;
  position: relative;
}

#ball {
  position: absolute;
  left: 0; /* relatif ke posisi terdekat blok atas (lapangan) */
  top: 0;
  transition: 1s all; /* Animasi CSS untuk left/top untuk membuat bolanya terbang */
}

Selanjutnya kita harus mengatur dengan benar ball.style.left/top. Mereka memiliki koordinat relatif ke lapangan(field) sekarang.

Berikut ini gambarnya:

Kita memiliki event.clientX/clientY – koordinat relatif jendela (window) dari klik.

Untuk mendapatkan koordinat kiri relatif terhadap lapangan(field), kita kurangkan dengan nilai dari ujung dan pembatas kiri lapangan:

let left = event.clientX - fieldCoords.left - field.clientLeft;

Biasanya, ball.style.left artinya “ujung kiri dari elemen” (bola). Jadi kita mengatur nilai left, kemudian ujung bola, bukan tengah, akan berada tepat dibawah kursor mouse.

Kita perlu memindahkan bola setengah lebar kiri dan setengah tinggi atas untuk membuatnya di tengah.

Jadi nilai terakhir left akan menjadi:

let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;

Koordinat vertikal di ukur dengan menggunakan logika yang sama.

Harap dicatat bahwa lebar/tinggi bola harus di ketahui pada saat kita mengakses ball.offsetWidth. Sebaiknya di atur pada HTML atau CSS.

Buka solusi di kotak pasir.

pentingnya: 5

Buat sebuah menu yang terbuka/tertutup pada saat ditekan:

Tambahan: HTML/CSS dari dokumen harus dimodifikasi.

Buka sandbox untuk tugas tersebut.

HTML/CSS

Pertama buat HTML/CSS.

Sebuah menu adalah komponen tersendiri pada halaman, jadi lebih baik untuk menaruhnya kedalam satu elemen DOM.

Sebuah daftar dari item menu bisa dapat diatur kedalam daftar menggunakan ul/li.

Ini contoh strukturnya:

<div class="menu">
  <span class="title">Manis-Manis (Tekan saya)!</span>
  <ul>
    <li>Kue</li>
    <li>Donat</li>
    <li>Madu</li>
  </ul>
</div>

Kita dapat menggunakan <span> untuk judul, karena <div> memiliki display:block, dan akan memenuhi 100% horisontal lebar elemen.

Seperti ini:

<div style="border: solid red 1px" onclick="alert(1)">Manis-Manis (Tekan saya)!</div>

Jadi jika kita mengatur onclick pada judul, maka itu akan menangkap klik diselah kanan teks.

Sedangkan <span> memiliki display:inline, dan akan memenuhi ruang yang cukup sesuai dengan teks:

<span style="border: solid red 1px" onclick="alert(1)">Manis-Manis (Tekan saya)!</span>

Membuka dan menutup menu

Membuka dan menutup menu seharusnya menganti posisi anak panah dan menunjukan atau menyembunyikan daftar menu.

Semua pergantian ini sangat sempurna untuk di tanggani oleh CSS. Pada Javascript kita harus memberi label pada kondisi menu saat ini dengan menambahkan/menghapuskan kelas(class) .open.

Tanpanya, menu akan tetap tertutup:

.menu ul {
  margin: 0;
  list-style: none;
  padding-left: 20px;
  display: none;
}

.menu .title::before {
  content: '▶ ';
  font-size: 80%;
  color: green;
}

…Dan dengan .open anak panah akan berubah dan daftar akan kelihatan:

.menu.open .title::before {
  content: '▼ ';
}

.menu.open ul {
  display: block;
}

Buka solusi di kotak pasir.

pentingnya: 5

Ada sebuah daftar pesan.

Gunakan Javascript untuk menambahkan tombol untuk menutup pada bagian pojok kanan atas setiap pesan.

Hasil seharusnya seperti ini:

Buka sandbox untuk tugas tersebut.

Untuk Menambahkan tombol kita bisa menggunakan position:absolute (dan membuat pane position:relative) atau float:right. float:right memiliki keuntung dimana tombol tidak akan perna tumpang tindih dengan teks, tetapi position:absolute memberikan lebih banyak kebebasan. Jadi pilihannya pada kamu.

Kemudian pada setiap pane kodenya akan seperti ini:

pane.insertAdjacentHTML("afterbegin", '<button class="remove-button">[x]</button>');

Kemudian <button> menjadi pane.firstChild, jadi kita tambahkan sebuah penangan seperti ini:

pane.firstChild.onclick = () => pane.remove();

Buka solusi di kotak pasir.

pentingnya: 4

Buat sebuah Carousel – pita gambar yang dapat digulir dengan mengklik panah.

Nanti kita akan menambahkah lebih banyak fitur: pengguliran tanpa batas, pemuatan dinamis dan seterusnya.

Tambahan: untuk tugas ini, struktur HTML/CSS merupakan 90% dari solusi.

Buka sandbox untuk tugas tersebut.

Pita gambar bisa di diwakili sebagai ul/li daftar dari gambar <img>.

Biasanya, pita seperti itu sangat luas, tapi kita akan menambahkan ukuran tetap pada <div> untuk “memotong” pita, jadi hanya sebagian dari pita yang kelihatan:

Untuk menampilkan daftar secara horisontal kita perlu menambahkan properti CSS yang benar pada <li>, seperti display: inline-block.

Untuk <img> kita sebaiknya juga mengatur display, karena bawaanya merupakan inline. Ada For <img> we should also adjust display, because by default it’s inline. Ada ruang ekstra yang disediakan di bawah elemen inline untuk “ekor huruf”, jadi kita bisa menggunakan display:block untuk menghapusnya.

Untuk membuat pengulirannya, kita bisa menggeser <ul>. Ada banyak cara untuk melakukannya, contohnya dengan menganti margin-left atau (performa lebih baik) gunakan transform: translateX():

<div> luar memiliki lebar tetap, jadi gambar “ekstra” dipotong.

Keseluruhan carousel adalah “komponen grafis” mandiri pada halaman, jadi sebaiknya kita membungkusnya menjadi satu <div class="carousel"> dan menata elemen-elemen ke dalamnya.

Buka solusi di kotak pasir.

Peta tutorial