본문 바로가기

웹 개발/JavaScript

JS (2) : Style 및 Event

이 게시물은 Nomadcoders의 JS 무료강의를 참고하여 작성하였다.

바닐라 JS로 크롬 앱 만들기 – 노마드 코더 Nomad Coders

 

바닐라 JS로 크롬 앱 만들기 – 노마드 코더 Nomad Coders

Javascript For Beginners

nomadcoders.co

 

이전 JS 포스팅에서 HTML에서 어떤 것을 가져오는 방법에 대해 배웠다.

이번엔 특정 element를 가져와서 style을 조작하고 event를 처리하는 방법에 대해 알아보자.

 

우리가 가져온 element 내부를 확인해 보자.

element 내부를 확인하고 싶다면 console.dir() 을 사용하면 된다.

 

이전 포스팅에서 사용한 HTML에서 다음과 같이 수정해 주었다.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div class="hello">
            <h1>Grab me1!</h1>
        </div>

        <script src="jsExJS.js"></script>
    </body>
</html>

JS파일의 코드는 다음과 같다.

 

const title = document.querySelector('.hello h1');
console.dir(title);

 

 

실행 결과는 다음과 같다.

현재 우리가 가져 온 element 내부에 있는 property들을 보여주고 있다.

잘 살펴보다 보면, on으로 시작되는 property들이 있을 것이다.

이것들이 event를 담당한다.

 

우선, event를 조작하기 전에 style property를 조작해 보자.

 

Style

console.dir()을 통해 살펴본 JS object 내부 property에서 style이라는 property를 찾을 수 있을 것이다.

 

 

현재 element에 적용되어 있는 style을 JS 형식으로 확인할 수 있다. 

그렇다면 이 요소를 조작해서 style을 바꿔보자.

 

js파일에 다음 코드를 추가해 보자.

title.style.color = 'blue';

 

글자가 파란색으로 바뀐 것을 확인할 수 있다.

이런 식으로 JS 파일에서 요소에 스타일을 적용시킬 수 있다.

 

Event

JS에서 대부분 작업하는 일은 event를 listen 하는 것이다. 그렇다면 event란 무엇일까?

 

event란, 말 그대로 어떤 사건을 의미한다. 여기서 사건이란, 사용자가 어떤 것을 클릭하거나, 드래그하거나, 무언가를 입력하는 등 사용자와의 상호작용을 통해 일어나는 사건을 의미한다.

 

그렇다면, 이 event를 listen하는 방법을 알아보자.

우선, click event부터 listen해 보자.

 

Click Event

JS코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    console.log('title was clicked');
}

title.addEventListener('click', handleTitleClick);

우리는 title에 addEventListener를 추가했다. 이를 통해, 특정 이벤트가 발생했을 때 그 이벤트를 감지할 수 있다. 이벤트를 지정하는 방법은, addEventListener의 첫 번째 인자에 특정 이벤트를 넣어주면 된다. 현재 우리는 click event를 감지할 것이기 때문에 첫 번째 인자에 "click"을 넣었다.

 

그리고 event가 발생했을 때 동작하는 함수를 만들어 추가해 주었다. EventListener와 함수를 연결하기 위해서, EventListener의 두 번째 인자에 함수명(handleTitleClick)을 넣어 주었다.

주의할 점은, 두 번째 인자에 함수명을 넣을 때 함수명만 넣어줘야 한다는 점이다. 현재 eventListener에게 함수 명을 넘겨주는 것으로, JS는 event가 발생했을 때 인자로 받은 함수명을 가진 함수를 실행한다. 하지만 ()를 포함해서 함수명을 전달하면 JS는 곧바로 함수를 실행한 후, event가 발생하더라도 이 함수를 다시 실행하지 않는다.

 

Event 찾기

우리가 listen할 수 있는 다른 event들을 찾기 위해선 어떻게 하면 될까?

정답은 구글링이다. 모든 event들을 외울 수 없기 때문이다.

 

HTMLElement - Web APIs | MDN (mozilla.org)

 

HTMLElement - Web APIs | MDN

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.

developer.mozilla.org

이벤트를 찾는데 많은 도움이 되는 사이트이다. 

 

또는, 직접 console.dir()을 통해서 확인할 수도 있다. property 이름 앞에 on이 붙어있다면, 그것은 event listener이다.

여기서 주의할 점은, event를 사용할 때에는 onclick -> click처럼 on을 제거한 명칭을 사용해야 한다.

 

구글링과 console.dir()을 사용해서 원하는 event들을 처리하는 eventListener를 직접 만들어 보자.

 

Event listener 할당 방법

우선, event를 listen하는 방법을 다시 한번 알아보자.

 

1. addEventListener()을 이용해서 event를 listen 한다.

이는 우리가 사용한 방식이다.

2. oneventname property에 event listener를 할당함으로써 event를 listen 한다.

이는 object 내부에 있는 property에 직접 event listener를 할당하는 것이다.

 

click event에서 event listener를 할당하는 방법을 다음과 같이 수정할 수 있다는 말이다.

 

title.addEventListener('click'handleTitleClick); => title.onclick = handleTitleClick;

 

1번 방법을 사용했을 때 좋은 점은 나중에 removeEventListener를 통해서 event listener를 쉽게 제거할 수 있다는 점이 있다.

 

JavaScript로 CSS 조작하기

우리가 만들었던 이 코드를 통해, 유저가 title을 클릭했을 때 title을 파란색으로 바꾸고, 한 번 더 클릭했을 때 title을 tomato 색으로 바꾸어 보자.

 

우선, JS 코드를 아래와 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    console.log(title.style.color);
    title.style.color = 'blue';
    console.log(title.style.color);
}

title.addEventListener('click', handleTitleClick);

수정 후, title을 클릭해 보면 다음과 같을 것이다.

 

 

우리는 title.style.color로 title에 적용되어 있는 글자 색을 가져올 수 있고, title.style.color = "blue" 로 title에 적용되어있는 글자 색을 수정할 수 있다.

첫 번째 줄이 비어있는 이유는 기존에 아무 값도 들어있지 않았기 때문이다.

한 번 더 눌러보면, 다음과 같은 결과가 나올 것이다.

 

 

기존의 색은 blue이고, 수정 후의 색이 blue로 정상 동작 하는 것을 볼 수 있다.

그렇다면, if else문을 통해서 우리가 원하는 코드를 작성할 수 있을 것이다.

 

다음과 같이 JS 코드를 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    if (title.style.color === 'blue') {
        title.style.color = 'tomato';
    } else {
        title.style.color = 'blue';
    }
}

title.addEventListener('click', handleTitleClick);

 

===은 JS에서 사용하는 연산자이다. 일치 연산자라고 부른다. 이는 비교하는 대상과 자료형까지 완벽히 동일하면 true를 반환한다.

 

간단하다. h1.style.color가 "blue"라면, "tomato"로 바꿔주고, 그렇지 않으면 "blue"로 바꿔준다.

그럼 이제 코드를 조금 더 보기 좋게 바꿔보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    const currentColor = title.style.color;
    let newColor;
    if (currentColor === 'blue') {
        newColor = 'tomato';
    } else {
        newColor = 'blue';
    }
    title.style.color = newColor;
}

title.addEventListener('click', handleTitleClick);

 

보는 사람들로 하여금 코드를 더 쉽게 이해할 수 있도록 JS 코드를 수정해 주었다.

 

하지만 이렇게 JS 코드에서 CSS를 수정하게 된다면, 유지 보수를 할 때 디자인을 수정하는 경우 CSS 파일뿐만 아니라 JS 파일까지 함께 수정해야 한다는 단점이 있다.

그렇기 때문에, 우리는 CSS 파일에서 이러한 기능들을 수행할 예정이다.

 

CSS 파일에서 JS 활용하기

우선, CSS 파일을 만들어서 우리가 작업하고 있는 HTML 파일에 연결해 주자.

나는 styleJS.css 파일을 만들어서 HTML 파일에 연결해 주었다.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <link rel="stylesheet" href="/styleJS.css" />
    </head>
    <body>
        <div class="hello">
            <h1>Grab me1!</h1>
        </div>

        <script src="jsExJS.js"></script>
    </body>
</html>

 

이후, css 파일을 다음과 같이 수정해 주자.

 

h1 {
    color: blue;
}

.active {
    color: tomato;
}

 

.active라는 클래스를 어떠한 element에 지정해 주면, 어떠한 element도 tomato color를 가지게 될 것이다.

 

그렇다면, 이제 JS에서 title에 active class를 전달해 주면 될 것 같다.

JS 코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    title.className = 'active';
}

title.addEventListener('click', handleTitleClick);

 

결과를 확인해 보자.

 

 

하지만 tomato 색인 title을 다시 클릭하면 blue 색으로 변하지 않는다. 

그 기능을 추가해 보자.

JS 코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    if (title.className === 'active') {
        title.className = '';
    } else {
        title.className = 'active';
    }
}

title.addEventListener('click', handleTitleClick);

 

이제 원하는 기능을 수행하는 모습을 볼 수 있다.

CSS를 통해 디자인을 수정하기 때문에, CSS 파일을 입맛대로 수정한다면 클릭을 했을 때 여러 가지 Style을 한 번에 바꿀 수 있다.

 

기능은 완성했지만, 아직 코드가 깔끔한 것은 아니다.

우선, "active"라는 문자열을 2번 사용하고 있다. 이는 개발자가 이렇게 적겠다고 선택한 것이고, 이것을 raw value라고 한다. 이 raw value를 사용한다면 오타를 내는 등 문제가 발생하기 쉽다.

 

코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    const clickedClass = 'active';
    if (title.className === clickedClass) {
        title.className = '';
    } else {
        title.className = clickedClass;
    }
}

title.addEventListener('click', handleTitleClick);

 

clickedClass라는 const 변수를 선언하여, active 위치에 대신 사용해 주었다. 이제 우리는 const 변수를 입력할 때 오타가 발생하면, console 창에서 확인할 수 있다.

 

아직, 수정할 것이 남아있다.

만약 h1 태그에 class가 이미 있다면 어떻게 될까?

그 class는 사라지고 active가 추가될 것이다. 그렇다면 모든 class name을 날려버리지 않고, active class만 변경하려면 어떻게 해야 할까?

 

정답은, classList를 만드는 것이다.

classList는 말 그대로, class들의 목록으로 작업할 수 있게끔 허용해 준다.

className은 이전 class들은 상관하지 않고 모든 것을 교체한다. 하지만 classList에서는, 조금 다르게 동작한다.

classList에는 contains라는 function이 있다. 이 function은 우리가 명시한 class가 HTML element의 class에 포함되어 있는지 말해주는 것이다.

 

JS 코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    const clickedClass = 'active';
    if (title.classList.contains(clickedClass)) {
        title.classList.remove(clickedClass);
    } else {
        title.classList.add(clickedClass);
    }
}

title.addEventListener('click', handleTitleClick);

 

contains를 이용해서 clickedClass가 있는지 확인하고, 있다면 remove()를 통해 지워준다. 만약 없다면, add()를 통해서 추가해 준다. 

HTML 파일로 돌아가서, h1 태그에 아무 class나 추가한 후 결과를 확인해 보자.

 

 

우리가 원하는 대로 동작하는 것을 확인할 수 있다.

이러한 작업은 개발을 진행하다 보면 굉장히 흔하게 하는 작업이다. 그러므로, 이를 편하게 해 주는 function 또한 존재한다.

그 함수는 toggle()이라는 함수이다.

이 함수는 class name이 존재하는지 확인하고, class name이 존재한다면 remove를 진행하고, 없다면 add를 진행한다.

toggle()을 사용하여 코드를 다시 작성해 보자.

 

JS 코드를 다음과 같이 수정해 보자.

 

const title = document.querySelector('.hello h1');

function handleTitleClick() {
    title.classList.toggle('active');
}

title.addEventListener('click', handleTitleClick);

 

const 변수를 사용하지 않은 이유는, 우리가 'active'라는 문자열을 한 번만 사용하기 때문이다. 이럴 때는 굳이 const 변수를 만들어서 오류를 방지하는 작업을 하지 않아도 된다.

우리가 원하는 기능을 단 한 줄의 코드로 완성했다!

 

이로써, 우리는 JS를 사용하는 기초적인 지식을 얻었다.

이제 간단한 페이지를 만들면서 배웠던 내용을 응용해 보도록 하자.