티스토리 뷰

과제를 진행하는데 getElementsByClassName에 addEventListener를 쓰면 계속 오류가 났다. 일단은 getElementsByClassName 대신 getElementById를 사용해서 해결했는데 왜 그런지 궁금해서 찾아봤다.

 

querySelector와 getElementById는 단일 DOM 객체를 불러와서 addEventListener사용에 문제가 없지만, querySelectorAll과 getElementsByClassName은 NodeList를 가져온다. 여러 요소를 선택하는 메소드 뒤에는 직접적으로 addEventListener를 사용할 수 없는 것 같다. MDN 문서에도 querySelector와 getElementById는 단일 Element를 반환한다고 되어있고 querySelectorAll은 NodeList, getElementsByClassName은 HTMLCollection을 반환한다고 되어있다.

 

  <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" />
    <script defer src="./addEventListener.js"></script>
    <style>
      .red {
        color: red;
      }
    </style>
    <title>Document</title>
  </head>
  <body>
    <button class="btn">red</button>
    <ul>
      <li class="list-item">item1</li>
      <li class="list-item">item2</li>
      <li class="list-item">item3</li>
      <li class="list-item">item4</li>
    </ul>
  </body>

 

querySelectorAll

const liElement = document.querySelectorAll(".list-item");

const liElement = document.querySelectorAll(".list-item");
const button = document.querySelector(".btn");

function colorRed() {
  liElement.forEach((item) => {
    item.classList.add("red"); // 글씨가 빨간색으로 바뀜
  });
}
button.addEventListener("click", colorRed);

 

getElementsByClassName

const liElement = document.getElementsByClassName("list-item");

// 불가능
const liElement = document.getElementsByClassName("list-item");
const button = document.querySelector(".btn");

function colorRed() {
  liElement.forEach((item) => {
    item.classList.add("red"); // 에러발생 : liElement.forEach is not a function. 
  });
}
button.addEventListener("click", colorRed);

 

// 해결방법 1
// for문으로 HTMLCollection을 새로운 배열에 담기
const liElement = document.getElementsByClassName("list-item");
const button = document.querySelector(".btn");

let newliElement = [];
for (let i = 0; i < liElement.length; i++) {
  newliElement.push(liElement[i]);
}

function colorRed() {
  newliElement.forEach((item) => {
    item.classList.add("red");
  });
}
button.addEventListener("click", colorRed);

 

// 해결방법 2
// Array.from() 사용하기
const liElement = document.getElementsByClassName("list-item");
const button = document.querySelector(".btn");

let newliElement = Array.from(liElement);

function colorRed() {
  newliElement.forEach((item) => {
    item.classList.add("red");
  });
}
button.addEventListener("click", colorRed);

 

// 해결방법 3
// 전개구문으로 HTMLCollection을 새로운 배열에 담기
const liElement = document.getElementsByClassName("list-item");
const button = document.querySelector(".btn");

let newliElement = [...liElement];

function colorRed() {
  newliElement.forEach((item) => {
    item.classList.add("red");
  });
}
button.addEventListener("click", colorRed);

 

querySelectorAll과 getElementsByClassName에 addEventListener를 쓰고 싶다면 반복문을 사용해서 각각 붙여주면 된다. 요소가 하나일 경우에는 인덱스 번호를 명시하고 addEventListener를 사용하면 된다.

 

HTMLCollection, Nodelist 등은 ‘유사 배열 객체(array-like object)’라서 index 접근이 가능하고, length 속성이 있다. 하지만 배열의 네이티브 메소드는 쓸 수 없다. forEach()메소드도 HTMLCollection은 사용불가하다. 인덱스로 접근하거나 새 배열을 만들어 순회해야한다.

+ 스터디 팀원분이 알려주신 정보! 감사합니다


백준 step1 입출력과 사칙연산 1 ~ 11

미루고 미뤄왔던 백준 문제 풀기를 드디어 시도했다. 전에 두세번 도전했다가 자바스크립트로 어떻게 제출하고 채점하는지를 모르겠어서 포기했는데 회원가입하고 문제로 들어가니까 제출 탭이 있어서 그동안 미뤄왔던게 머쓱해졌다.

제출 탭에서 언어를 선택하고 코드 공개여부를 선택한 뒤 에디터에 코드를 붙여넣고 제출을 누르면 된다. 그러면 채점이 진행되고 정답여부를 알려준다. 입력이 있는 문제는 채점까지 시간이 조금 걸린다. 

 

문제는 입력값이 있는 문제였는데 구글링을 해봐도 당최 무슨 말인지 이해할 수 없었다. 모두들 '평균은 되겠지' 문제를 예시로 들어서 설명하는데 이해불가능이었다. 변수를 여러 개 사용하는 함수를 처음 접했을 때처럼 분명 한국말인데도 알아듣지 못하는 그 기분이 오랜만에 들었다......... 입력을 정제해서..... 네......? 그렇게 찾다가 정답은 백준 도움말에서 발견했다. 공식문서를 읽으라는 말을 다시 한번 체감했다. 역시 공식문서를 읽어야한다! 공식문서 최고!!!

node.js로 예제 입력 받기

 

한번에 푸는 문제가 드물긴 하지만... 스스로의 멍청함에 열이 받긴 하지만.... 입력이 없는 문제조차도 여러 번 틀리고... 10172번 강아지 문제도 4번만에 풀었지만....... 퀴즈쇼 푸는 것 같고 승부욕이 생겨서 재미있다. 막상 해보니 재밌어서 미뤘던게 아쉽다. 그럼 더 많은 문제를 풀었을텐데.. 매번 처음 진입장벽이 높아보이면 금방 포기하는 것 같다. 앞으로는 일단 몸통박치기 해야지.


10701, 10172

이스케이프 문자를 사용해서 푸는 것이 핵심이다.

\를 입력하려면 \\로 입력해야한다.

'나 "나 `를 한개만 입력하려면 \를 붙여서 입력해야한다. (\' \" \`)

 

10869

입력 받아온 값을 숫자로 변환해주는 것이 필요하다.

넷째줄 A/B에 Math.floor도 사용했는데 자꾸 틀렸다고 해서 검색 했더니 문자열이어서 틀린 것 같다. 까먹지 말고 숫자로 변환해야겠다.

입력 받아오는 코드를 넣어서 결과를 미리 보고 싶은데 어떻게 하는지 몰라서 찾아봐야겠다. 이건 결과를 못봐서 틀린거다......

var fs = require("fs");
var input = fs.readFileSync('/dev/stdin').toString(); // 입력 받아오는 코드

+단항 연상자를 사용하면 Number()처럼 사용할 수 있다.

let a = +input[0]; // let a = Number(input[0]);
let b = +input[1]; // let b = Number(input[1]);

 

10926

공백을 없애는 trim()을 사용해야한다.

분명 정답이겠거니 하며 당당하게 풀었는데 또 틀려서 찾아보니 예제에 공백이 있었다. 앞으로는 예제를 복사해서 푸는 습관을 들여야겠다. 검색해보니 공백을 split(' ')으로 분리해도 틀리고 trim()을 사용해야만 정답인 문제 같다고 한다.

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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 30 31
글 보관함