Two articles in a row, sebenarnya sudah lama hanya tinggal menulis ulang saja. Kali ini kita akan membuat blurr effect, semacam efek kabur yang dapat diaplikasikan pada menu untuk menampilkan fokus. Jadi idenya ketika mouse berada pada menu tertentu, menu yang lain akan nge-blur. Kita akan menerapkan blurr effect dengan 3 metode berbeda. Siapkan 3 file andalan kita.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Blurr Effect</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="header">
<div class="menu">
<a class="link" href="#">Hello</a>
<a class="link" href="#">How</a>
<a class="link" href="#">Are</a>
<a class="link" href="#">You</a>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
/* style.css */
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.header {
height: 100vh;
background-color: burlywood;
display: flex;
align-items: center;
justify-content: center;
}
.header .menu {
background-color: chocolate;
width: 900px;
display: flex;
justify-content: space-around;
height: 100px;
align-items: center;
font-size: 50px;
font-weight: bolder;
border-radius: 9999px;
border: 2px solid #efefef;
}
.header .menu a {
text-decoration: none;
transition: all 0.7s ease-out;
}
Cara Pertama
Kita akan menggunakan event mouseover dan mouseout serta memanfaatkan DOM traversal closest. Untuk closest sudah pernah kita gunakan pada proyek sebelumnya, saya sendiri juga termasuk yang baru mengetahui metode closest ini, kalau dari MDN docs penjelasannya sebagai berikut :
The closest() method of the Element interface traverses the element and its parents (heading toward the document root) until it finds a node that matches the specified CSS selector. Return value : the closest ancestor Element or itself, which matches the selectors. If there are no such element, null.
Jadi penjelasan singkatnya metode closest mencari keatas (parent/anchestor) sampai menemukan selector yang dicari atau dirinya sendiri
// app.js
menu.addEventListener('mouseover', (e) => {
if (e.target.classList.contains('link')) {
// menentukan target
const link = e.target;
// menentukan menu lain selain target
const siblings = link.closest('.menu').querySelectorAll('.link');
// jika menu lain bukan target (tidak terkena mouseover) maka opacity diset 0.2
siblings.forEach((el) => {
if (el !== link) el.style.opacity = 0.2;
});
}
});
menu.addEventListener('mouseout', (e) => {
if (e.target.classList.contains('link')) {
const link = e.target;
const siblings = link.closest('.menu').querySelectorAll('.link');
siblings.forEach((el) => {
if (el !== link) el.style.opacity = 1;
});
}
});
Hasilnya
Cara kedua
Kita akan mencoba me-refactor kode diatas supaya lebih rapi karena ada kode yang berulang (rekursif). Untuk refactor kita buat fungsi baru
// refactor
const handleOver = function (e, opacity) {
if (e.target.classList.contains('link')) {
const link = e.target;
const siblings = link.closest('.menu').querySelectorAll('.link');
siblings.forEach((el) => {
if (el !== link) el.style.opacity = opacity;
});
}
};
menu.addEventListener('mouseover', handleOver(e, 0.5));
menu.addEventListener('mouseout', handleOver(e, 1));
Kode diatas akan menghasilkan error sebagai berikut
Kenapa ? Karena metode addEventListener memerlukan sebuah fungsi untuk parameter keduanya, bukan sembarang variabel. Maka kita akan mem-passing fungsi sebagai berikut (hasilnya sama dengan diatas jadi saya tidak akan memperlihatkan)
const menu = document.querySelector('.menu');
menu.addEventListener('mouseover', function (e) {
handleOver(e, 0.2);
});
menu.addEventListener('mouseout', function (e) {
handleOver(e, 1);
});
Cara ketiga
Cara terakhir kita akan menggunakan bind method yang juga pernah kita bahas disini. Bind method akan mengembalikan (return) fungsi yang dengan atribut/keyword 'this' yang bisa diisi nilai apapun
const handleOver = function (e) {
if (e.target.classList.contains('link')) {
const link = e.target;
const siblings = link.closest('.menu').querySelectorAll('.link');
siblings.forEach((el) => {
if (el !== link) el.style.opacity = this;
});
}
};
menu.addEventListener('mouseover', handleOver.bind(0.2));
menu.addEventListener('mouseout', handleOver.bind(1));
Argument pada bind hanya bisa diisi single value, apabila membutuhkan lebih bisa passing data berupa array
Top comments (0)