DEV Community

Cover image for Blurr Element - JavaScript & CSS
boibolang
boibolang

Posted on

Blurr Element - JavaScript & CSS

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>
Enter fullscreen mode Exit fullscreen mode
/* 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;
}
Enter fullscreen mode Exit fullscreen mode

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;
    });
  }
});
Enter fullscreen mode Exit fullscreen mode

Hasilnya

file

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));

Enter fullscreen mode Exit fullscreen mode

Kode diatas akan menghasilkan error sebagai berikut

file

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);
});
Enter fullscreen mode Exit fullscreen mode

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));

Enter fullscreen mode Exit fullscreen mode

Argument pada bind hanya bisa diisi single value, apabila membutuhkan lebih bisa passing data berupa array

Top comments (0)