Home JavaScript 입문 2
Post
Cancel

JavaScript 입문 2

querySelectorAll()

기존 querySelector을 이용해 하나의 요소를 가져올 수 있었습니다.
그렇다면, query에 선택되는 요소들을 모두 가져오려는 경우는 어떻게 할까요?

네 맞습니다. querySelectorAll을 이용해 가져오면 되겠죠.

다만 querySelectorAll을 배우기 전에 먼저 querySelector을 이용해 수정을 적용하는 방법에 대해서 알아봐야 합니다.
우리는 document에 querySelctor을 적용해 특정 요소를 가져옵니다.
이후 해당 요소에 .style과 같은 값을 변경하게 되죠.

그렇다면, 마찬가지로 querySelectorAll을 이용해 모두 가져와 변경하려면 가져온 요소들에 .style값을 변경하면 될까요?

정답은 ‘아니다’입니다.
컴퓨터는 querySelectorAll을 통해서 모든 요소를 가져왔는데 이를 배열([]) 이라는 바구니로 가져옵니다.
그렇기에 document.querySelectorAll().style 같은 형식으로 적용하게 되면, 바구니에 style을 적용하려는 형식이기에 에러가 발생합니다.

따라서 우리는 명확하게 컴퓨터에게 어떤 작업을 수행하려고 하는지 전달해줘야합니다.

예를 들어서 가져온 모든 요소 중 첫번째 요소를 바꾸려면 아래와 같이 전달해야 합니다.

1
document.querySelectorAll(".container-text")[0].style.color = "white";

위의 코드는 class가 container-text인 요소들을 모두 가져와 그 중 0번째 즉, 1번째 요소의 color을 white로 변경하는 코드입니다.

  • 컴퓨터는 1번째 요소를 0번이라고 부릅니다. 따라서 2번째 요소는 1번 요소가 되는거죠.

querySelectorAll 예제

아래는 list형식의 쇼핑 목록 html 예제 코드 입니다.

1
2
3
4
5
6
<ul class="list-container">
  <li class="list-item">맨투맨 티셔츠</li>
  <li class="list-item">스니커즈 신발</li>
  <li class="list-item">청바지</li>
  <li class="list-item">맨투맨 티셔츠</li>
</ul>

해당 목록에는 첫번째와 마지막에 맨투맨 티셔츠가 중복으로 들어와 있습니다.
마지막 요소인 맨투맨 티셔츠를 후드티로 바꿔야 합니다.

먼저 코드를 작성하기 전에 해야되는 작업이 하나 있습니다.
내가 작성해야 되는 내용을 정리하고 코드를 작성하는 것이 좋기에 간략하게 문제 해결 방법을 적어보겠습니다.

html 문서에서 list-item들을 모두 가져온 뒤, 그 중 4번째 요소의 내부 html을 “후드티”로 변경한다.
Javascript에서는 아래와 같습니다.

1
document.querySelectorAll(".list-item")[3].innerHTML = "후드티";
  • 앞서 말씀드린것과 같이 1번째 요소가 0번이므로, 4번째 요소는 컴퓨터에게 3번입니다.

if - else 조건문

자, 그렇다면 innerHTML 요소가 청바지인 item을 반바지로 바꿀 수 있을까요?
마찬가지로 querySelectorAll()[2]번째 요소를 변경하면 작동하겠지만, 이번에는 조금 더 프로그래머스럽게 작성해보겠습니다.

바로 조건문을 통해서, innerHTML 요소가 청바지면, item을 변경하는 것이죠.
조건문은 다음과 같은 형식으로 작성합니다.

1
2
3
4
5
6
7
if(조건식) {
  조건식이 참인경우 실행
} else {
  조건식이 거짓인 경우 실행
}

여기서 조건식은 ‘요소의 innerHTML이 “청바지”와 같으면(==)’정도로 정의 할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
if (document.querySelectorAll(".list-item")[0].innerHTML == "청바지") {
  document.querySelectorAll(".list-item")[0].innerHTML = "반바지";
}
if (document.querySelectorAll(".list-item")[1].innerHTML == "청바지") {
  document.querySelectorAll(".list-item")[1].innerHTML = "반바지";
}
if (document.querySelectorAll(".list-item")[2].innerHTML == "청바지") {
  document.querySelectorAll(".list-item")[2].innerHTML = "반바지";
}
if (document.querySelectorAll(".list-item")[3].innerHTML == "청바지") {
  document.querySelectorAll(".list-item")[3].innerHTML = "반바지";
}

자, 여기까지 잘 따라오신분이면 위의 코드를 보고 떠오르는 내용이 하나 있어야 합니다.
바로 코드가 불필요하게 중복되어 있다는 점이죠.

이를 해결하기 위해 우리가 배웠던 function을 이용해 다음과 같이 작성할 수도 있겠네요 !

1
2
3
4
5
6
7
8
9
function changeName(index) {
  if (document.querySelectorAll(".list-item")[index].innerHTML == "청바지") {
    document.querySelectorAll(".list-item")[index].innerHTML = "반바지";
  }
}
changeName(0);
changeName(1);
changeName(2);
changeName(3);

변수

이렇게 if문과 function을 이용했음에도 코드가 길어보입니다.
이를 조금 더 축소 시킬 수 있을까요?

이를 위해서 변수를 이용해 값을 저장하는 법에 대해서 알아보겠습니다.

변수는 자주 사용하는 자료의 값을 저장 할 수 있습니다.
예를 들어서, 내가 “안녕하세요 저는 자바스크립트를 배우고 있습니다.”라는 인사말을 저장하고 싶다면 다음과 같이 저장해서 쉽게 꺼내 쓸 수 있습니다.

1
2
3
var 이름 = "안녕하세요 저는 자바스크립트를 배우고 있습니다.";

요소.innerHTML = 이름;

이런식으로 미리 지정된 변수 이름을 통해 손쉽게 값을 저장하고 사용 할 수 있습니다.
그렇다면 쇼핑 list에서 아래와 같이 요소를 변수에 저장해 사용 할 수 있겠네요 !

1
2
3
4
5
6
7
8
9
10
function changeName(index) {
  var item = document.querySelectorAll(".list-item")[index];
  if (item.innerHTML == "청바지") {
    item.innerHTML = "반바지";
  }
}
changeName(0);
changeName(1);
changeName(2);
changeName(3);

이외에도 숫자 값을 넣은 뒤 간단한 연산을 진행 할 수도 있습니다.

1
2
3
4
5
6
var count = 0;

//count에 count+1을 저장하는 3가지 방법;
count = count + 1;
count++;
count += 1;

for 반복문

function을 이용했음에도 코드가 불필요하게 반복되어있다고 생각됩니다.
이러한 문제를 해결하기 위해 반복문을 이용 할 수 있습니다.

반복문은 다음과 같은 형식으로 사용합니다.

1
2
3
for(변하는  초기화; 조건식;  증가  감소 ){
  반복되는 내용
}

간단하게 설명하면, 변수를 정의 한 뒤, 해당 변수가 조건식을 만족할 때 까지 증가 및 감소하는 식을 매 반복때마다 적용하는 형식입니다.

아래는 변수가 3보다 작을때 까지 증가하는 반복문 입니다.

1
2
3
4
5
6
7
8
9
10
11
for (var i = 0; i < 3; i++) {
  반복되는 내용
}

// 1. 처음 i 값은 0이므로 0 < 3은 참이기에 반복되는 내용 실행
// 2. 이후 i 값은 0 + 1이므로 1 < 3은 참이기에 반복되는 내용 실행
// 3. 이후 i 값은 1 + 1이므로 2 < 3은 참이기에 반복되는 내용 실행
// 4. 이후 i 값은 2 + 1이므로 3 < 3은 거짓이기에 반복문 종료

//따라서 1,2,3과 같이 3번 실행된다.

그렇다면 list-item에도 반복문을 적용할 수 있을까요?

반복문을 사용하기 좋은 경우는 증가 및 감소 식에 맞는 특정한 규칙이 필요합니다.
예를 들어서 2, 4, 6과 같이 2씩 증가하는 변수를 사용하는 경우나, 함수에 0,1,2 와 같은 값을 반복해서 전달해야 하는 경우입니다.

아래는 list-item을 반복문을 이용해 출력한 경우입니다.

1
2
3
4
5
6
7
8
9
function changeName(index) {
  var item = document.querySelectorAll(".list-item")[index];
  if (item.innerHTML == "청바지") {
    item.innerHTML = "반바지";
  }
}
for (var i = 0; i < 4; i++) {
  changeName(i);
}

i값이 4보다 작을동안 i값이 증가하면서 반복한다. 이때, changeName에 i 값을 전달해줍니다.
즉, 기존과 같이 changeName(0),changeName(1), changeName(2), changeName(3)을 수행하게 됩니다.

JavaScript 예제

자, 그러면 이제 우리는 JavaScript에서 HTML 요소를 가져와 수정 하는 방법을 배웠습니다.
querySelector, getElementById 등 특정 요소들을 가져와 style.color, innerHTML 등의 방법으로 요소를 수정 할 수 있었습니다.

그리고 for 반복문, if 반복문, var 변수, function 함수 등 다양한 JS 기능들을 배웠습니다.

이제 이러한 기능들을 활용해 보는 예제 풀이를 진행해봅니다.

간단한 다크모드

  • 문제상황 : 버튼을 누르면 count 클래스의 값이 1씩 증가합니다.
    count 클래스의 값이 홀수이면 컨테이너 박스의 색상이 검정색으로, 글자 색은 하얀색으로 바뀝니다.
    count 클래스의 값이 짝수이면 컨테이너 박스의 색상이 흰색으로, 글자색이 검정색으로 바뀝니다.

다음과 같은 코드에서 script 부분을 작성해주세요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>테스트</title>
  </head>
  <body>
    <div class="container">
      <p class="count">0</p>
      <button class="btn-click">클릭</button>
    </div>
  </body>
  <style>
    .container {
      width: 100%;
      height: 100vh;
      background-color: #eee;
    }
    p {
      font-size: 24px;
    }
    .btn-click {
      width: 30%;
    }
  </style>
  <script></script>
</html>

저는 아래와 같이 구현했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
document.querySelector(".btn-click").addEventListener("click", function () {
  document.querySelector(".count").innerHTML++;

  // var number = Number(document.querySelector(".count").innerHTML);
  // number += 1;
  // document.querySelector(".count").innerHTML = number;

  if (document.querySelector(".count").innerHTML % 2 == 0) {
    document.querySelector(".container").style.backgroundColor = "white";
    document.querySelector(".container").style.color = "black";
  } else {
    document.querySelector(".container").style.backgroundColor = "black";
    document.querySelector(".container").style.color = "white";
  }
});

중간에 주석처리 한 부분은 html이 문자(string)여서 숫자로(number)으로 변환하여 +=1 처리 해주는 부분입니다.
++으로 계산 시 자동으로 형변환(문자에서 숫자로 변환)이 되어 작동합니다.

여기서 중요한 점은 3가지 정도가 있습니다.

  1. 버튼이 눌러졌을 때, 상황(evnet)이 발생한다는 점.
  2. 버튼이 눌러졌을 때 count 값이 올라간다는 점.
  3. count 값의 짝수, 홀수에 따라 container의 style이 변한다는 점.

상세하게 설명하자면, 모든 변화는 사용자가 버튼이 눌러졌을 때 발생하고, 그 이후 바로 count 값이 올라간 뒤 count 값에 따라 style이 변한다는 점입니다.

따라서, 모든 event는 click listener안에서 동작해야합니다.

입력에 따른 별 생성

  • 문제상황 : 사용자가 입력한 수에 따라 “*“으로 이루어진 탑이 star 클래스의 자식으로 생성된다.
    (Ex: 3을 입력시 아래와 같은 탑이 생성된다.)

    *
    **
    ***

    값이 바뀌면 기존의 “*“들은 삭제되고 입력한 수에 따른 “*“이 다시 생성된다.

    이때, 홀수번째 별은 붉은색 짝수번째 별은 푸른색으로 설정한다.

html은 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>별 생성하기</title>
  </head>
  <body>
    <div class="container">
      <input type="number" min="0" class="count" />
    </div>
    <div class="star"></div>
  </body>
  <script></script>
</html>
  • Tip 필요한 능력 for 반복문, if 조건문, 입력 이벤트 리스너
    javascript 컴포넌트 자식 지우기
    javascript input 값 가져오기
    javascript 요소 생성 및 추가하기
    javascript 문자열 반복하기

예시 답안은 다음과 같습니다.

혼자 풀어봐야 실력이 늡니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
document.querySelector(".count").addEventListener("input", function () {
  document.querySelector(".star").innerHTML = "";
  const input = document.querySelector(".count").value;

  for (var i = 0; i < input; i++) {
    const star = document.createElement("p");

    star.innerHTML = "*".repeat(i + 1);
    if (i % 2 == 1) {
      star.style.color = "red";
    } else {
      star.style.color = "blue";
    }
    document.querySelector(".star").append(star);
  }
});

예제를 잘 풀었을까요?

어려우신 분들도 있으실거고 잘 해결하신 분들도 계실거라고 생각됩니다.
개인적으로 자바스크립트는 결국 지금까지 배운 내용의 반복이라고 생각합니다.

문법을 배우고, 이를 응용하는 간단한 반복이죠.

그래서 결국 프로그래밍적인 사고를 하실 줄 알게된다면 앞으로 배워나가는데 문제가 없으리라 생각합니다.
간단하게 정리하자면, 문제상황을 파악하고 해당 문제를 해결하기 위해 컴퓨터에게 구체적인 명령을 내릴줄 알아야 합니다.

자바스크립트부터는 전부 적기에는 내용이 방대하여 이만 줄이겠습니다.

This post is licensed under CC BY 4.0 by the author.

JavaScript 입문 1

Typescript 01