프로그래밍/JavaScript

[JS] DOM 연습

삐제제 2021. 1. 15. 03:08

 

 

 

 

 

html 요소를 id나 클래스, 태그를 통해 가져올 때 :

// title 이라는 클래스를 가진 요소를 title 변수에 저장
const title = document.querySelector(".title");

// title 이라는 id를 가진 요소를 title 변수에 저장
const title = document.querySelector("#title");

// body 라는 태그를 가진 요소를 body 변수에 저장
const body = document.querySelector("body");

 

가져온 요소를 이벤트 리스너를 통해 제어하는 방법 :

// title 클래스를 가진 요소를 변수 title에 저장.
const title = document.querySelector(".title");

// 이벤트를 처리해줄 함수
// title의 색상을 바꿔준다.
function handleMouseOver() {
	title.style.color = #eebc12;
}

// 이벤트 리스너를 등록한다.
// addEventListener 함수의 매개변수로는 (발생한 이벤트, 처리할 함수) 가 들어간다.
title.addEventListener("mouseover", handleMouseOver);

 

 

이벤트의 종류는 다음 문서에서 참조할 수 있다.

developer.mozilla.org/ko/docs/Web/Events

 

이벤트 참조 | MDN

DOM 이벤트는 발생한 흥미로운 것을 코드에 알리기 위해 전달됩니다. 각 이벤트는 Event 인터페이스를 기반으로한 객체에 의해 표현되며 발생한 것에 대한 부가적인 정보를 얻는데 사용되는 추가

developer.mozilla.org

문서 객체 모델 (DOM) 의 종류도 다음 문서에서 참조할 수 있다.

developer.mozilla.org/ko/docs/Web/API/Document_Object_Model

 

문서 객체 모델(DOM) - Web API | MDN

문서 객체 모델(DOM)

developer.mozilla.org

 

js 파일 내에서 css가 하는일들을 하고싶지 않을때:

이게 무슨 말이냐면, HTML 작업은 HTML 파일에서하고, CSS 작업은 CSS파일에서하고,

JS 작업은 JS 파일에서 해야한다는 말이다.

즉 자바 스크립트는 CSS로 할 수 있는 스타일 작업이 아닌 자바스크립트에서는 로직을 처리하고 싶은것이다.

 

이를 위해 클래스를 이용하여 처리하는 방법을 이용할 수 있다.

css 파일에 상황마다 적용시킬 효과들을 미리 만들어 놓고, js 파일에서는 이벤트가 발생하면 그 만들어놓은 효과를 html 의 클래스나 id로 붙여주는 것이다!

 

const MY_COLOR = #eebc12;
const OTHER_COLOR = #904ead;
const title = document.querySelector("#title");

function handleClick() {
	const checkcolor = title.style.color;
    if(checkcolor === MY_COLOR) {
        title.style.color = OTHER_COLOR;
    } else {
        title.style.color = MY_COLOR;
  }
}



// 초기화 함수
function init() {
    title.style.color = MY_COLOR;
 	title.addEventListener("click", handleClick);   
}
init();

위와 같이 작동하는 코드가 있다고 하면, 아래와 같이 코딩하는것이다.

 

/* CSS 파일 */

#title {
    color: #eebc12;
}

.clicked {
    color: #904ead;
}

 

// JS 파일

const title = document.querySelector("#title");
const CLICKED_CLASS = "clicked"; // 변수 CLICKED_CLASS 에 문자열 "clicked" 를 저장한 것


function handleClick(){
    const currentClass = title.className; // title 변수가 가진 className을 저장
    if(currentClass !== CLICKED_CLASS) {
        title.className = CLICKED_CLASS;
    } else {
        title.className = "";
    }
}


function init() {
 	title.addEventListener("click", handleClick);   
}
init();

요렇게 CLICKED_CLASS 안의 문자열로 html 태그의 클래스를 컨트롤 할수 있게되는것이다~

 

하지만 만약 클래스를 덧붙여서 하는 작업을 한다면 문제가 생길것이다.

 

예를들어 바로 위 예 같은경우i d가 있는 태그를 다뤘기때문에 클래스이름을 동적으로 추가해주어도 원래 클래스 네임이 없었기때문에 상관이없었다.. 하지만 이미 클래스네임을 가지고있는 태그를 컨트롤 하려고한다면?? 그리고 그 이미 가지고 있는 클래스네임에는 원래 적용하던 CSS효과가 적용되있는 상태라면?

 

저 코드처럼하게된다면 clicked 클래스네임만 가지게되어.. 그 전에 적용되어있던 효과는 모두 날아가버릴것이다..

 

하지만 이를 위한 방법이 있다.. 바로바로 Element.classList를 사용하는것이다.

 

사용방법은 아래를 보자.

 

// JS 파일

const title = document.querySelector("#title");
const CLICKED_CLASS = "clicked"; // 변수 CLICKED_CLASS 에 문자열 "clicked" 를 저장한 것


function handleClick(){
    const currentClass = title.className; // title 변수가 가진 className을 저장
    if(currentClass !== CLICKED_CLASS) {
        title.classList.add(CLICKED_CLASS);
    } else {
        title.classList.remove(CLIKED_CLASS);
    }
}


function init() {
 	title.addEventListener("click", handleClick);   
}
init();

이렇게 해주면

title.classList.add(CLICKED_CLASS) 에서

원래 있던 클래스명에 clicked 클래스가 덧붙여 지는것이기 때문에

<h1 id="title" class="origin clicked">Hello</h1> 이런식으로 추가가된다.

또, title.classList.remove(CLICKED_CLASS) 에서는 CLICKED_CLASS ("clicked") 의 클래스 명만 지우게되어

원래 받고 있던 효과도 사라지지 않게된다.

 

그런데 위 코드도 문제가있다. 한번 클릭하게되면 else 문으로 넘어가지 않는다는것.. 그 이유는

currentClass !== CLIKED_CLASS 이 조건이 항상 참으로 들어가기 때문이다..

 

why? title.className 을 하게되면.. 하나의 클래스만 가져온다.

클릭을 하게되면 클래스명은 origin 에서 origin clicked 를 가지게 되는것이다. 따라서 항상 다르다!!

 

그래서 여기 필요한건 contains 이다!

 

(classList 에 관한 MDN 문서)

developer.mozilla.org/ko/docs/Web/API/Element/classList

 

contains도 위에 링크한 MDN문서에 나와있는것인데,

 

지정된 클래스값이 엘리먼트의 class 속성에 있는지 없는지 확인을 시켜주는것이다.

 

따라서 이를 이용해 코드를 수정하면? 최종적으로는 다음과 같은 코드가 된다.

 

 

// JS 파일

const title = document.querySelector("#title");
const CLICKED_CLASS = "clicked"; // 변수 CLICKED_CLASS 에 문자열 "clicked" 를 저장한 것


function handleClick(){
    const checkClass = title.classList.contains(CLICKED_CLASS); // true or false 를 반환함. 있으면 true 없으면 false
    
    if(!checkClass) {
        title.classList.add(CLICKED_CLASS);
    } else {
        title.classList.remove(CLIKED_CLASS);
    }
}


function init() {
 	title.addEventListener("click", handleClick);   
}
init();

 

toggle을 사용해서 코드를 좀 더 간단하게 만들수도 있다!

 

// JS 파일

const title = document.querySelector("#title");
const CLICKED_CLASS = "clicked"; // 변수 CLICKED_CLASS 에 문자열 "clicked" 를 저장한 것


function handleClick(){
    title.classList.toggle(CLICKED_CLASS);
}


function init() {
 	title.addEventListener("click", handleClick);   
}
init();

위와 같이 작성하면 우리가 위에서 했던 것과 똑같은 역할을 하는 코드가 된다!