Interaksi JavaScript dan CSS
Published: 2024-02-17 08:42:16

JavaScript dapat dipakai untuk memanipulasi property CSS dalam sebuah website sehingga menjadi lebih interaktif. Pertama buatlah file html, css dan tentu saja javascript sederhana sebagai berikut.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="styles.css" />
    <title>Title</title>
  </head>
  <body>
    <header>This is header</header>
    <script src="note.js"></script>
  </body>
</html>
```

```css
:root {
  --color-primary: #fd424b;
}

header {
  color: var(--color-primary);
  font-size: 30px;
  font-weight: bold;
}
```
Tampilan awal seperti berikut.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nbv1gva2ufldedoao8m.png)

Berikut adalah contoh-contoh mainpulasi CSS dengan JavaScript.

**Create html element**
Untuk membuat elemen html digunakan perintah sebagai berikut.

```javascript
const message = document.createElement('div'); // Membuat elemen
message.classList.add('cookie-message'); // Memberi nama class
message.innerHTML = 'This is cookie <button class="btn">Close</button>'; // Isi dari elemen <div> yang baru saja dibuat
```
Setelah elemen html yang diinginkan dibuat selanjutnya adalah menempatkan elemen tersebut. Beberapa metode untuk menempatkan elemen html sebagai berikut :

- prepend : menempatkan elemen html sebelum elemen lainnya sebagai first-child
- append : menempatkan elemen html setelah elemen lainnya sebagai last-child
- before : menempatkan elemen html sebelum elemen lainnya sebagai sibling
- after : menempatkan elemen html setelah elemen lainnya sebagai sibling

_prepend_
Dengan perintah sebagai berikut di javascript `header.prepend(message);` didapatkan hasil sebagai berikut.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpbo7mkv7oov2w74030m.png)
Jika kita _inspect_ halaman html tersebut, terlihat bahwa elemen `<div>` yang kita buat menjadi first-child dari `<header>`.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gokv0cghl3zbp1158vya.png)

_append_
Dengan perintah sebagai berikut `header.append(message);` maka hasilnya sebagai berikut.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ne4u6g1mf35vwh79ra2.png)
Kemana elemen `<div>` yang ada diatas `<header>` ? Kalau kita _inspect_ halaman didapatkan sebagai berikut.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54q378cl837n2nvoi504.png)
Benar bahwa perintah `append` membuat elemen menjadi last-child tapi kemanakah elemen `<div>` yang berada diatas `<header>` ? Jawabannya adalah karena elemen html yang kita buat merupakan _live element_ jadi akan terus diupdate dan tidak bisa berada pada dua tempat sekaligus. Lantas bagaimana jika kita ingin menampilkan keduanya ? Gunakanlah perintah `header.append(message.cloneNode(true));` maka didapat hasil sebagai berikut.

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41wc7sd0y8ie1pz8rxe2.png)

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tp4qkv02kyn4wmfyilu6.png)

Perintah `header.before(message);` dan `header.after(message);` menghasilkan tampilan yang sama, hanya saja elemen html yang dihasilkan posisinnya akan berbeda sebagai berikut.

_before_ dan _after_

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0odhkcai4dlc75kapys.png)

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9cgleeynczr2sipld1v.png)
Terlihat bahwa posisi `div` dan `header` adalah sejajar, dalam DOM disebut sebagai sibling. Silahkan dicoba sendiri untuk metode `header.after(message);` dan `header.after(message.cloneNode(true));`.

**Delete html element**
Tentunya elemen yang dibuat juga harus bisa dihapus. Kita akan menghapus elemen yang tadi dibuat dengan tombol, maka kita membutuhkan _event driven method_ yaitu `eventListener`.

```javascript
document.querySelector('.btn').addEventListener('click', function () {
  message.remove();
  // Sebelum adanya remove()
  // message.parentElement.removeChild(message);
});
```
![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yu9dgn9xf0tzo2jg1ve.gif)

**CSS Style**
Nilai maupun property dari CSS dapat kita manipulasi dengan JavaScript. Penulisan property di JavaScript untuk memanipulasi CSS menggunakan aturan _camel case_ misalkan kita biasa menulis di CSS `backgroud-color` maka di JavaScript penulisannya menjadi `backgrounddColor`.

```javascript
message.style.backgroundColor = '#5ec576';
message.style.width = '80%';
```

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4a5s2okivgzpz7bag94.png)
Mengambil nilai dari property CSS.

```javascript
// Mengambil nilai style
console.log(message.style.color); // Tidak mengembalikan apa-apa
console.log(message.style.backgroundColor); // Output: rgb(94, 197, 118)
```
Mengapa `console.log(message.style.color);` tidak mengembalikan nilai apapun ? Itu dikarenakan nilai dari property CSS yang bisa diambil adalah jika CSS tersebut bertipe inline style, jika tidak maka dianggap tidak ada atau berada diluar (eksternal CSS). Supaya eksternal CSS bisa dikenali dan diambil nilai property-nya digunakan perintah sebagai berikut.

```javascript
// Cara supaya bisa diambil nilai property jika bukan inline style
console.log(getComputedStyle(message).color); // Output: rgb(187, 187, 187)
console.log(getComputedStyle(message).height); // Output: 48.3333px
```
Hasil dari metode `getComputedStyle` berupa _string_ untuk menjadikannya `Number` digunakan metode sebagai berikut.

```javascript
// getComputedStyle menghasilkan string, gunakan Number.parseFloat
message.style.height = Number.parseFloat(getComputedStyle(message).height, 10) + 30 + 'px';
console.log(getComputedStyle(message).height); // Output: 51.3229px
```

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us6f2gggc1vx43peio3e.png)

Kita juga bisa merubah custom property atau pre-defined property sebagai berikut.

```javascript
// Merubah custom property style
document.documentElement.style.setProperty('--color-primary', 'blue');
```

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mz3kdk0n6ajjyda8pqas.png)

**Attribute**
Untuk keperluan demo kita tambahkan logo dan button pada file html kita sehingga menjadi seperti ini.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="styles.css" />
    <title>Title</title>
  </head>
  <body>
    <header>This is header</header>
    <img data-version-number="3.0" designer="john" src="img/logo.png" alt="Bankist logo" class="nav__logo" id="logo" />
    <a class="nav__link--btn" href="#">Click</a>
    <script src="note.js"></script>
  </body>
</html>
```

![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/assxoy3sqo0fg6wzafyb.png)
Beberapa metode yang bisa kita pakai sebagai berikut.

```javascript
// Mendapatkan nilai atribut
const logo = document.querySelector('.nav__logo');
console.log(logo.alt); // Output: Bankist logo
console.log(logo.src); // Output: http://127.0.0.1:5500/img/logo.png, absolute path
console.log(logo.getAttribute('src')); // Output: img/logo.png, relative path
console.log(logo.className); // Output: nav__logo

// Non-standard attribute: attribut yang dibuat sendiri tidak akan dikenali
console.log(logo.designer); // Output: undefined

// Cara supaya dikenali
console.log(logo.getAttribute('designer')); // Output: john

// Setting attribut
logo.alt = 'It is beautiful';
logo.setAttribute('company', 'bankbot');
console.log(logo.alt); // Output: It is beautiful
console.log(logo.getAttribute('company')); // Output: bankbot

const link1 = document.querySelector('.nav__link--btn');
console.log(link1.href); // Output: http://127.0.0.1:5500/index.html#
console.log(link1.getAttribute('href')); // Output: #

// Special atribut: data-
console.log(logo.dataset.versionNumber); // Output: 3.0

// Classes
logo.classList.add('c', 'j'); // Menambahkan class 'c' dan 'd'
// logo.classList.remove('c', 'j'); // Menghapus class
logo.classList.toggle('j'); // Menyembunyikan class 'j' sehingga tersisa class 'nav__logo' dan 'c'
console.log(logo.classList.contains('c')); // Output: true

// Jangan lakukan
// logo.className = 'bobi'; // Akan mengganti semua nama class
```