Deteksi prefer-color-scheme dengan Javascript
Bagian Dari Seri ✦ Implementasi Dark Mode
Mukadimah
Section titled MukadimahDi tulisan terakhir, kita sudah mengimplementasikan dark mode pada website menggunakan CSS variable, data-attribute dan javascript sebagai kontrolnya. Sekarang kita akan membawanya ke ‘level selanjutnya’.
Secara otomatis merubah tema berdasarkan preferensi warna sistem operasi pengguna dan menyimpan pengaturannya menggunakan jadi saat pengguna reload laman tema yang dipilih tidak ter-reset.
Menambah pendeteksi preferensi warna sistem operasi pengguna.
Section titled Menambah%20pendeteksi%20preferensi%20warna%20sistem%20operasi%20pengguna.Sebelumnya kita sudah membuat function toggleTheme()
, sekarang kita tulis kode untuk mendeteksi preferensi warna sistem operasi pengguna ketika website pertama kali dimuat menggunakan Window.matchMedia Web API
function toggleTheme() { // ... Kode Sebelumnya ...}
// Akan dipanggil saat website dimuatwindow.onload = (event) => { // Definisikan query apa yang akan kita cek const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); // Jika cocok, setel data-theme ke nilai dark. Jika tidak, ke nilai light if (mediaQuery.matches) document.documentElement.setAttribute("data-theme", "dark"); else document.documentElement.setAttribute("data-theme", "light");};
Sekarang, saat website dimuat tema akan otomatis berubah berdasarkan preferensi warna sistem operasi pengguna. Tapi masih ada kekurangan disini, tema website tidak akan berubah saat pengguna mengubah preferensi warna sistem operasi mereka. Untuk itu kita tambah listener
untuk “mendengar” perubahan tersebut.
// Fungsi untuk tombol pengubah temafunction toggleTheme() { // ... Kode sebelumnya ...}
// Akan dipanggil saat website dimuatwindow.onload = (event) => { // ... Kode sebelumnya ...
// Tambah listener untuk cek perubahan real-time mediaQuery.addListener((e) => { if (e.matches) document.documentElement.setAttribute("data-theme", "dark"); else document.documentElement.setAttribute("data-theme", "light"); });};
Horray! Sekarang website kita sudah bisa mendeteksi perubahan preferensi warna pengguna. Tapi website kita belum menyimpan pengaturan pengguna saat merubah tema di website-nya sendiri. Saatnya kita simpan tema terakhir yang dipilih pengguna menggunakan Web API lainnya yaitu Window.localStorage
Simpan Pengaturan Tema Pengguna.
Section titled Simpan%20Pengaturan%20Tema%20Pengguna.Idenya simple, ketika pengguna mengganti tema, kia simpan pengaturannya ke local storage menggunakan Window.localStorage , dan jika kita mendatangi website lagi, kita cek pengaturan pengguna yang sudah kita simpan dan terapkan ke website. Okay, cukup penjelasannya, ayo kita implementasikan!
function toggleTheme() { /* Jika document memiliki atribut data-theme dengan nilai dark */ if (document.documentElement.getAttribute("data-theme") === "dark") { /* Setel atribut menjadi light */ document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); // Simpan ke local storage } else { /* Jika tidak, setel ke dark */ document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); // Simpan ke local storage }}
// Akan dipanggil saat website dimuatwindow.onload = (event) => { // Definisikan query apa yang akan kita cek const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); // Kita cek dari localStorage apa ada data theme if (localStorage.getItem("theme") === "dark" || "light") document.documentElement.setAttribute( "data-theme", localStorage.getItem("theme"), ); else { // Jika data di local storage tidak ditemukan, // setel berdasarkan preferensi warna pengguna. if (mediaQuery.matches) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); // Simpan ke local storage } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); // Simpan ke local storage } } // Tambah listener untuk cek perubahan real-time mediaQuery.addListener((e) => { if (e.matches) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); // Simpan ke local storage } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); // Simpan ke local storage } });};
Kita baru saja mengimplementasikan makenisme simpan pengaturan untuk tema. Tapi javascript kita terlihat berantakan, banyak pengulangan disana. Ayo kita coba rapikan agar kodingan lebih ‘cantik’.
Bonus. Waktunya Refactor!
Section titled Bonus.%20Waktunya%20Refactor%21Seperti yang bisa kita lihat, setiap kita menyetel tema, kita selalu memanggil document.documentElement.setAttribute
dan localStorage.setItem
, sepertinya kita bisa membuat fungsi terpisah untuk ini lalu tinggal panggil fungsinya saja.
/* Fungsi untuk mengubah tema */function changeTheme(theme) { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("theme", theme);}
/* Fungsi untuk tombol pengubah tema */function toggleTheme() { if (document.documentElement.getAttribute("data-theme") === "dark") { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); changeTheme("light"); } else { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); changeTheme("dark"); }}
/* Akan dipanggil saat website dimuat */window.onload = (event) => { /* Cek theme berdasarkan localStorage pengguna */ if (localStorage.getItem("theme") === "dark" || "light") { document.documentElement.setAttribute( "data-theme", localStorage.getItem("theme"), ); changeTheme(localStorage.getItem("theme")); } else { /* Cek melalui Window.matchMedia */ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); if (mediaQuery.matches) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); changeTheme("dark"); } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); changeTheme("light"); } } /* Tambah listener untuk mengecek perubahan secara real time preferensi warna pengguna yg dipilih */ mediaQuery.addListener((e) => { if (e.matches) { document.documentElement.setAttribute("data-theme", "dark"); localStorage.setItem("theme", "dark"); changeTheme("dark"); } else { document.documentElement.setAttribute("data-theme", "light"); localStorage.setItem("theme", "light"); changeTheme("light"); } });};
Ta-da! Sekarang kode kita jadi lebih rapi dan mudah dibaca kan? Semoga kalian menikmati dan menemukan tulisan ini berguna. Source code contoh tulisan ini bisa ditemukan dibawah
visualnaut/darkmode-css-variable
A simple implementation of dark mode on a website using CSS variable and javascript.