til

개인 과제 2일 차(完) @데이터 형태와 활용

fpzmfks 2024. 7. 26. 22:00

어제는 주구장창 데이터 형태를 공부하면서 코드를 조금 깔짝여보고, 오늘에 이르러 그 동안의 노력이 빛을 발하여 과제를 완료했다. 

 

 


페이지 렌더링과 함께 카드 생성, 돔 종료 후 검색 실행 기능 생성, 자식요소로 부모요소 검색, 홈 버튼과 위로 스크롤 버튼... 고난이 많았지만 대부분이 데이터 형태에 대한 무지에서 비롯된 것이었다. 

 

다행히 어제 주구장창 일반복사와 얕은 복사, 깊은 복사를 공부한 보람이 있어서 이를 이용해 과제를 끝 마칠 수 있었다. 

 

먼저 지난 잘못을 되돌아보자면, 저번에 페이지 렌더링를 끝마치지 못했던 것은 DOM을 제대로 다루지 못했기 때문이다. DOM을 잘못 이해하고 DOM으로 태그를 생성하는 부분을 for문에 돌리지 않고 변수 선언문처럼 사용하였으니 카드가 하나밖에 생성되지 않았고, 그 때문에 for문 자체는 잘 돌렸어도 실제 결과가 잘못되어 나타난 것이다. 

 

다만 페이지 렌더링을 위해 fetch로 불러온 데이터를 다룰 때 있었던 문제가 이것뿐만은 아니므로 어제 바짝 데이터 형태에 대해 공부하고 오늘 열심히 코드를 짜보았다. 또 데이터 형태 공부를 통해 콘솔을 찍어서 데이터를 확인하는 과정 또한 더욱 수월하게 할 수 있어서 가끔 문제가 생겨도 어디서 문제가 생겼는지 빠르게 확인할 수 있었다. 다행히 대부분 for문을 활용하여 이러한 문제를 해결할 수 있었고, 전개 연산자를 이용한 얕은 복사를 통해 배열이나 객체를 새롭게 생성하는 것으로 데이터 활용 문제를 해결할 수 있었다. 

 

비슷하지만 다른 문제로는 검색 기능을 구현하는 데에 필요한 부모요소/자식요소 찾기였는데, 여태껏 편하게만 써왔지만 일부의 값만으로 해당하는 요소를 불러온다는 것은 제법 복잡하다는 것을 알게되었다. 아마 나 같은 초보도 할 수 있는 걸 보면 또 그렇게까지 어려운 일은 아니겠지만서도....

 

부모요소 찾기는 closest으로 했는데, 

    let titleData = document.querySelectorAll(".contentTitle");
    let input = document.getElementById("inputBox");

    titleData.forEach((element) => {
      let searchWord = input.value.toLowerCase();
      let searchCard = element.innerText.toLowerCase();
      let cardData = element.closest(".oneCard");

 

이게 또 여기서 element가 div 그 자체가 아니였다면 또 다른 방법으로 코드를 짜야했을 수도 있다. 이번에는 document.querySelectorAll('자식요소 클래스명')으로 div들을 배열 형태로 불러와서 for문을 돌리는 것으로 자식요소/부모요소를 쉽게 배치할 수 있었다. 

 

데이터 형태를 배우고 또 하나 이해할 수 있게 된 것이, 키가 숫자로 저장되어 있는 것이었는데, 

document
    .getElementById("inputBox")
    .addEventListener("keyup", function (event) {
      // 검색창에서 엔터키(keyCode 13)를 눌렀다 떼면 검색 버튼을 클릭하라.
      if (event.keyCode === 13) {
        document.querySelector(".searchBtn").click();
      }
    });

데이터의 타입까지 동일해야 true를 반환하는 ===가 이렇게 작동하는 것을 보니 엔터키의 코드가 정말 숫자로 저장되어 있다는 것을 알 수 있었다. 

 

위쪽 사진에 나타나 있는 항상 화면에 표시된 위로 스크롤 버튼도 이번에 처음 구현해 본 것이다. 이전에 팀 프로젝트에서 메인프레임 틀 구현을 맡으면서 css를 좀 깊이 파고들다가 알게된 position을 이용해서 구현한 것인데, position:fixed페이지가 아니라 창을 기준으로 위치를 배치하는 것이기 때문에 페이지를 스크롤해도 항상 페이지 상에 표시될 수 있다. 

 

그리고 마지막으로 별 거 아닌 것 같으면서도 나를 꽤나 고생하게 한 것이 바로 숙제로 지정된 조건인 특정 메소드 2개 이상 활용하기이다. 내가 처음으로 이 모든 기능을 구현했을 때 짠 코드는 숙제에서 제시한 코드들 중 1개밖에 사용하지 않았기 때문에, 코드를 완성하고 난 뒤에 filter를 사용한 코드를 다시금 작성해야 했다. 그래서 js 파일이 2개가 되었다. 

 

아래는 2개의 js파일의 다른 부분만 따온 것이다. 

 

let search = () => {
    // contentTitle이라는 클래스를 가진 값 모두 불러와서 배열 생성
    let titleData = document.querySelectorAll(".contentTitle");
    let input = document.getElementById("inputBox");

    titleData.forEach((element) => {
      let searchWord = input.value.toLowerCase();
      let searchCard = element.innerText.toLowerCase();
      let cardData = element.closest(".oneCard");

      // 검색창에 입력된 값이 생성된 카드의 타이틀의 일부이면 보이고, 아니면 숨겨라
      if (searchCard.includes(searchWord)) {
        cardData.style.display = "";
      } else {
        cardData.style.display = "none";
      }
    });
    //검색 하고 검색창 초기화
    input.value = "";
  };

 

let search = () => {
    // contentTitle이라는 클래스를 가진 값 모두 불러와서 배열 생성
    let titleData = document.querySelectorAll(".contentTitle");
    let input = document.getElementById("inputBox");
    let searchWord = input.value.toLowerCase();

    // titleData는 배열이 아니기 때문에 그대로 쓸 수 없어서 전개 연산자로 얕은 복사를 사용
    let titleArr = [...titleData];

    // 맞는 정보, 맞지 않는 정보
    let correctData = titleArr.filter((c) => {
      let searchCard = c.innerText.toLowerCase();
      return searchCard.includes(searchWord);
    });

    let incorrectData = titleArr.filter((i) => {
      let searchCard = i.innerText.toLowerCase();
      return !searchCard.includes(searchWord);
    });

    // 필터링한 정보를 바탕으로 카드 표시,비표시
    correctData.forEach((element) => {
      let cardData = element.closest(".oneCard");
      cardData.style.display = "";
    });
    incorrectData.forEach((element) => {
      let cardData = element.closest(".oneCard");
      cardData.style.display = "none";
    });
    //검색 하고 검색창 초기화
    input.value = "";
  };

 

짧은 식견으로 코드 리뷰를 해보자면 역시 내가 처음 짰던 것이 짧고 간단한 것 같다. 그런데 어떤 글에서 if문을 사용하면 안 좋다는 말을 들어서 크게 자신은 없다. 그래도 짧은 게 더 좋지 않을까 한다. 

 

언젠가는 어떤 코드가 더 좋은 코드인지도 알 수 있게 되겠지... 부트 캠프를 하고 있는만큼 올해 안에 식견을 갖출 수 있게 되면 좋겠다. 

 

완성본