개발일기3 - 자바스크립트 쿼리셀렉터로 html 요소 불러오기
자바스크립트에서 html의 요소를 제어하기 위해서 사용하는 것이 바로 querySelector 이다.
querySelector를 사용해 자바스크립트에 연결하면 html을 작성하지 않더라도 브라우저에 나타나게 할 수 있다.
Problem
html 코드
<div id="quote">
<span></span>
<span></span>
<span></span> // 추가
</div>
js 코드
const quote = document.querySelector("#quote span:first-child");
const korean = document.querySelector("추가");
const author = document.querySelector("#quote span:last-child");
강의에서는 first-child와 last-child만 나왔지만 한국어 해석도 넣어주기 위해 한 줄을 더 추가하였다.
TRY
(1) second-child
첫 번째 span태그가 first-child니까 두 번째 span태그는 second-child로 넣어주었는데 이런 에러가 나왔다.
html
<div id="quote">
<span></span>
<span></span>
<span></span>
</div>
js
const quote = document.querySelector("#quote span:first-child");
const korean = document.querySelector("#quote span:second-child");
const author = document.querySelector("#quote span:last-child");
에러코드
Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#quote span:second-child' is not a valid selector.
second-child란 말을 사용하지 않는거 같았다. 인식조차 되지 않았다.
구글링을 해보니 이럴 때는 nth-child(숫자)를 사용한다 했다. 바로 적용해보았다.
(2) nth-child(숫자)
nth-child(숫자)를 사용해 바꿔주었다.
const quote = document.querySelector("#quote span:nth-child(0)");
const korean = document.querySelector("#quote span:nth-child(1)");
const author = document.querySelector("#quote span:nth-child(2)");
에러
Uncaught TypeError: Cannot set properties of null (setting 'innerText')
nth-child(숫자)를 사용했는데도 에러가 났다. 에러를 보고 콘솔을 찍어보니 quote의 값이 비어있었다.
(3) querySelectorAll
도저히 이해가 가지 않았다. 값이 비어있는 이유가 뭘까..?
코드를 꼼꼼히 살펴보았지만 이상한 곳이 없었다. 도저히 혼자서는 찾을 수 없을거 같아 동료분을 찾아갔다.
같이 머리를 맞대고 이상한 부분이 있나 찾아봤는데 아무리 찾아봐도 이상한 부분을 찾을 수 없었다.
이번에는 querySelectorAll을 사용해 출력해 보았다.
const quote = document.querySelectorAll("#quote span")[0];
const korean = document.querySelectorAll("#quote span")[1];
const author = document.querySelectorAll("#quote span")[2];
querySelectorAll을 사용해 출력했더니 아주 잘 나왔다.
물론 여기서 끝낼 수도 있지만 왜 querySelector을 사용했을 때는 제대로 나오지 않는지 이해가 가지 않았다..
(4) Re: nth-child(숫자)
갑자기 문득 떠오른 것 하나!
"#quote span:nth-child(숫자)" 이 부분이 css와 닮았다는 것이었다!
바로 숫자를 바꿔 보았는데 바로 성공!!!! 솔직히 너무 허탈했다..
css와 닮았다 생각했는데 css를 사용할 때 하는 방법과 똑같다는 것을 알게 되니 보이는 매직⭐️
const quote = document.querySelector("#quote span:nth-child(1)");
const korean = document.querySelector("#quote span:nth-child(2)");
const author = document.querySelector("#quote span:nth-child(3)");
Solution
(1) nth-child(숫자)
const quote = document.querySelector("#quote span:nth-child(1)");
const korean = document.querySelector("#quote span:nth-child(2)");
const author = document.querySelector("#quote span:nth-child(3)");
배열이 아닌 몇 번째를 나타내기 때문에 0부터가 아닌 1부터 시작해야 한다.
(2) querySelectorAll
const quote = document.querySelectorAll("#quote span")[0];
const korean = document.querySelectorAll("#quote span")[1];
const author = document.querySelectorAll("#quote span")[2];
querySelectorAll을 사용하면 첫 번째 child로 지정해주지 않아도 가지고 올 수 있다.
이 때에는 [0] 번째 부터 시작해 헷갈리지 않도록 주의가 필요하다.
Learning
querySelector를 사용할 때 이해가 잘 안가서 한참 걸렸다.
하지만 후에 css와 같다는 것을 알게 된 후 어렵지 않아졌다! 이걸 계기로 더 잘 활용할 수 있을거 같다.
+ 자바스크립트에서도 리액트에서 사용하는 것처럼 html을 사용할 수 있다는 것을 알게 되었다.(준방님 코드)
const $Body = document.querySelector("main");
const $SpanDiv = document.createElement("div");
$SpanDiv.id = "quote";
const $SpanArr = [
document.createElement("span"),
document.createElement("span"),
document.createElement("span"),
];
$SpanArr.forEach((e) => {
$SpanDiv.appendChild(e);
});
$Body.appendChild($SpanDiv);
const test = 0;
const quote = $SpanArr[0];
const korean = $SpanArr[1];
const author = $SpanArr[2];
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)]; // 개수 상관없이 작동
quote.innerText = todaysQuote.quote;
korean.innerText = todaysQuote.korean;
author.innerText = todaysQuote.author;
이럴 경우 html에 아무것도 없어도 태그를 입력할 수 있다.
<body>
<main></main>
</body>