JS 잔잔한 팁

Soo Im·2021년 7월 18일
0

잔잔한 팁

목록 보기
1/5
post-thumbnail

1. Event 감지

html/JS에서 event란 사용자가 어느 요소를 클릭하거나 값을 입력하는 등의 행위를 말한다. html상에서 event가 발생할 때 JS가 이를 감지하고 특정 동작을 실행하게 만들 수 있다.

const title = document.querySelector(".hello h1")

function userFuncClick() {
  console.log("User clicked .hello <h1>")	// click 발생시 작동하고 싶은 함수
}

title.addEventListner("click", userFuncClick)	// click을 감지하면 userFuncClick을 실행

위 코드에서 주목할 점은 userFuncClick()이 아닌 userFuncClick을 넘겨준다는 점이다. ()은 함수를 직접 사용하는 것이기 때문에 addEventLinstner가 함수를 사용하게 만드려면 ()은 제외하고 넘겨주어야 한다.

만약 userFuncClick()을 넘긴다면?
click event와 무관하게 항상 실행되므로 console을 열자마자 함수의 결과가 출력되어있다. 그리고 함수를 클릭하더라도 더 이상 실행되지 않는다.

event 종류에는 뭐가 있지?
console.dir(elementYouGet)을 하면 우리가 추출한 elementYouGet 객체 안의 property가 나온다. 여기에서 앞에 on이 붙은 property가 event이다. 예를 들어 onclick, oncopy, onmouseleave 등이 있다.

.addEventListener.onXX 비교
아래 두 script는 동일하게 동작한다. 다만 .addEventListener을 사용하면 반대로 .removeEventListener을 사용할 수 있기 때문에 이를 더 자주 사용한다.

element.addEventListener("click", userFunc);
element.onClick = userFunc;

2. constlet의 사용

(NomadCoder JS-3.6 CSS in Javascript 강의의 부가설명입니다.)
const는 값이 변하지 않는 변수(상수라고 해야 하나), let은 값이 변하는 변수를 정의할 때 사용한다는 것을 알고 있다. 막상 구분해서 쓸 일이 자주 있을까 싶지만 함수 등을 만들 때 유용하다.
html에서 myVar이라는 요소를 가져와서 이벤트가 발생할 때 myVar 색깔이 파란색이면 빨간색으로, 빨간색이면 파란색으로 바꾸는 함수를 만든다고 가정해보자.

function ChangeColor(){
    if (myVar.style.color === "blue"){
        myVar.style.color = "red";
    }
    else {
        myVar.style.color = "blue";
    }
}

// .addEventListener은 생략

이제 반복되는 myVar.style.color을 변수로 선언한다고 해보자.
이 때 if 조건으로 들어가는 color는 정해진 값을 받아오는 것이므로 변하지 않는다. 따라서 const currentColor = myVar.style.color로 정의하면 된다.
반대로 if 절 내의 color는 변동하므로 let을 사용해야 한다. 그렇다면 위와 동일하게 let newColor = myVar.style.color로 하면 될까?

// 함수 속에서 변수 선언하기 (잘못된 방법)
function ChangeColor(){
    const currentColor = myVar.style.color;	// 정해진 값을 받아오므로 const
    let newColor = myVar.style.color;	// 값이 변동하므로 let?
    if (currentColor == "blue"){
        newColor = "red";
    }
    else {
        newColor = "blue";
    }
}

이렇게 하면 될 것 같지만 막상 코드를 실행해보면 되지 않는다. 그 이유는 newColor의 값을 바꾼다고 그것이 myVar.style.color에 적용되지 않기 때문이다.

let newColor = myVar.style.color; 
console.log(newColor)	// 출력값: blank(myVar 색상이 정해지지 않은 경우)
newColor = "blue";	
console.log(newColor);	// 출력값: blue
console.log(myVar.style.color);	// 출력값: blank

코드에서 등식(=)은 실제로 둘이 항상 연동되어 같다는 의미가 아니라, 우항에서 좌항으로 값을 건내주는 방식이기 때문에 그런 것이다. 그래서 myVar의 값을 바꾸면 myVar의 값만 바뀌는 것이지 myVar.style.color도 함께 바뀌는 것이 아니다.
코드를 올바르게 고치면 다음과 같다.

// 함수 속에서 변수 선언하기 (옳은 방법)
function ChangeColor(){
    const currentColor = myVar.style.color;
    let newColor;	// 어차피 바꿀거니까 굳이 myVar.style.color을 받아올 필요가 없다
    if (currentColor == "blue"){
        newColor = "red";
    }
    else {
        newColor = "blue";
    }
  myVar.style.color = newColor;	// 이렇게 해야 newColor의 새로운 값이 myVar에 적용된다.
}

3. HTML 기능으로 JS 대체하기

JS로 모든 것을 구현하기보다 html의 기능을 적절히 사용하는 것이 유리하다. 예를 들어 input 변수 입력 여부와 길이를 JS로 확인하면 다음과 같지만

const username = loginInput.value;
if (username==="") {
    alert("Please write your name.");
}
else if (username.length > 10){
    alert("Your name is too long.");
}
... 
}

HTML로는 input 자체에서 required, maxlength로 위 조건을 바로 만들 수 있다. (대신 form을 사용해야 한다.

<form id='login-form'>
        <input required maxlength="10" type="text" placeholder="What is your name?" />
        <button>Log In</button>
</form>

이렇게 button까지 form 안에 넣어주면 input의 변수가 자동으로 전달되기 때문에 JS에서 굳이 button.addEventListener을 해 줄 필요도 없다.

4. localStorage에 저장된 아이디를 삭제해주는 log-out 버튼 만들기

NomadCoder JS-4.6 Loading Username 강의에서 localStorage에 저장된 username이 없으면 로그인 화면을, username이 있으면 'Hello username!'이 나오는 페이지를 만들었다. 여기에 로그아웃 기능을 추가해보았다.

원하는 로그아웃 기능
( 0. usernmae이 없으면 이름을 입력하는 log-in 화면이 나온다. )
1. username이 있을 때 'Hello username!'과 log-out 버튼이 나온다.
2. log-out 버튼을 누르면 loclaStorage에 저장된 username이 사라진다.
3. 그러면 다시 웹페이지를 리부팅해서 처음 단계로 돌아간다.

const loginForm = document.querySelector("#login-form")
const loginInput = document.querySelector("#login-form input");
const logoutForm = document.querySelector("#logout-form");	// log-out form 추가
const greeting = document.querySelector("h1");

const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";

const savedname = localStorage.getItem(USERNAME_KEY);

function onLoginSubmit(event){
    event.preventDefault();
    loginForm.classList.add(HIDDEN_CLASSNAME);
    const username = loginInput.value;
    localStorage.setItem(USERNAME_KEY, username);
    
    paintGreeting(username);
}

function paintGreeting(username){
    greeting.innerText = `Hello ${username}`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
    logoutForm.classList.remove(HIDDEN_CLASSNAME);	// log-out form이 나오도록 "hidden" 클래스를 삭제한다.
    logoutForm.addEventListener("submit", onLogoutSubmit);	// log-out form이 submit 되기를 기다린다.
}

function onLogoutSubmit(){
    localStorage.removeItem(USERNAME_KEY);	// log-out이 submit되면 username을 삭제한다.
    location.reload();	// 페이지를 다시 로드해서 처음으로 되돌아간다.
}

if (savedname === null) {
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit);
}
else {   
    paintGreeting(savedname);  
}

처음에는 logoutForm.classList.remove(HIDDEN_CLASSNAME);를 맨 밑의 else 문에 넣었는데 그렇게 하니 if일 때에는 (즉 저장된 이름이 없어 user가 직접 입력했을 때) log-out 버튼이 안 나오더라. 그래서 painGreeting 함수 안에 넣어서 user가 입력했든 원래 들어있든 'Hello'랑 항상 함께 나오도록 수정했다.

로그아웃이 잘 작동한다!

0개의 댓글