s e o p p o r t . l o g

Today I Learned

2024.01.09 TIL

Seo Ji Won 2024. 1. 9. 20:47

동적으로 만들어낸 요소 제어하기

브라우저 콘솔에서는 나오지만 vscode에서 입력하면 Cannot read properties of null 뜬다 -> 동적으로 추가한 요소이기 때문에 스크립트가 읽어들이지 못한다. 이벤트리스너로 클릭했을 때 어디서 이벤트가 발생했는지 알아와서 event.target으로 요소를 제어할 수 있다.

document.addEventListener('click', function (e) {
let ratingValue;
target = e.target;
if(target.id === "rating"){// 타겟의 아이디값이 rating인 경우
alert(ratingValue); //평점 alert

 

.json() 함수

개인과제 해설 영상을 보고 데이터를 받아올때 아예 영화데이터들만 받아오는 식으로 변경하려고 했다.

원래 데이터를 받아오는 코드는 이러했는데, 콘솔에 찍어보니 promise를 반환하고 있어서 키값으로 데이터에 접근할 수 없었다. 

const loadJson = async (URL) => {
  const response = await fetch(URL, options);
  if (response.status === 200) {
    const data = response.json();
    return data;
  }

 

그 이유는 .json() 메서드가 Promise를 반환하는 비동기 함수이기때문이다. 그렇기 때문에 await 키워드를 넣어주면 await가 Promise를 만나 실행 완료될때 까지 기다리고 원했던 영화 데이터 객체들만 얻을 수 있었다.

const data = await response.json();

 

 

코드 리팩토링

  • 버튼이 눌렸을 때와 엔터키가 눌렸을 때는 검색한 것에 맞는 카드만 추가하는 로직을 실행하게 되는데, 두 군데에 추가하는 로직을 둘 다 넣어버리니 뭔가 많이 비효율적인것 같았다. → 검색된 카드를 추가하는 함수를 따로 빼서 버튼, 엔터키가 눌렀을때 함수를 호출하게 하였다.
  • 원본의 데이터들로 카드를 만드는 함수와, 검색한 결과로 카드를 만드는 함수 두 곳에 데이터를 받아오는 코드가 중복되어 효율성이 떨어짐 → 데이터를 받아오는 과정을 따로 함수로 작성하여 리팩토링하였다.
  • 영화 객체 배열들을 받아와서, 변수에 각각 객체 키의 값들을 저장해놓았는데, 튜터님의 코드를 보고 필요없는 변수 선언과 할당 과정을 최소화 하고 HTML 태그 내에 바로 객체의 키값을 지정하여 데이터를 받아오게 하는 방법으로 바꾸었다.

 

버그잡기

검색창에 한글 입력 후 엔터를 치면 검색결과가 없음을 알리는 alert창이 두번 뜨는 버그가 발생했다.

const inputEnterPressed = document.getElementById("input-movie");
inputEnterPressed.addEventListener("keyup", function (e) {
  if (e.code === "Enter") {
    appendSearchedCard();
  }
});

Go버튼을 클릭하여 검색했을 때에는 버그가 발생하지 않았기 때문에 Enter의 이벤트 발생에서 한글입력에 대한 문제가 발생했을 것이라고 추론하였다. ‘한글 alert 두번’이라고 구글링해보니 해결법을 찾을 수 있었다.

이벤트리스너에 할당한 이벤트타입을 keyup → keypress로 바꾸니 해결할 수 있었다. 그런데 좀 더 찾아보니 keypress는 사용을 권장하지 않고 있다고 해서 다른 방법을 찾아보았다.

 

먼저 한글에서만 버그가 나는 이유는 한글이 자음과 모음의 조합으로 한 음절이 만들어지는 조합문자이기 때문이라고 한다. 영어는 한 음절이 하나의 알파벳으로 이루어지고, 조합문자가 아니기때문에 영어를 입력할 때는 버그가 발생하지 않았던 것이었다. 따라서 이벤트타입을 keydown으로 설정하고 isComposing이라는 입력된 글자가 조합되고있는지 아닌지 판단하는 함수를 사용해서 해결하였다. 콘솔로 e.isComposing을 찍어보면,

리을 밑에 밑줄이 쳐져있는것이 조합되고 있다는 뜻이다. 조합되고 있으므로 isComposin이 true를 반환하고, 입력을 마치고 커서가 맨 마지막에 위치했으므로 false를 반환한다. Enter키 한번에 결과를 두번 반환하고 있기 때문에 alert창이 두번 뜬 것이었다.

따라서 한글을 입력하고 방향키를 한번 눌러 조합이 완료된것으로 나타내면(밑줄 없어짐) false만 나오게 된다. 그러므로 isComposing 함수를 사용해서 true일때는 실행하지 않고, false일 때만 실행하게 하여 해결하였다. keydown으로 설정하는 이유는 위 내용과 비슷하게 keyup 이벤트는 한글 입력 시 조합 중일 때도 이벤트가 발생하기 때문이다.

inputEnterPressed.addEventListener("keydown", function (e) {
  if (e.code === "Enter") {
    if (!e.isComposing) {
      appendSearchedCard();
    }
  }

 

 

엔터키 검색 기능을 구현하다 우연히 발견한 것

input의 EventListener 안에 엔터키 조건을 걸지 않고 이벤트리스너만 걸면 엔터를 치지 않아도 새로고침 없이 검색하는 내용에 따라 검색된 카드들이 바뀐다. UX에 따라 활용할 일이 있을듯.

'Today I Learned' 카테고리의 다른 글

2024.01.16 TIL  (0) 2024.01.16
2024.01.15 TIL  (0) 2024.01.15
2024.01.12 TIL  (1) 2024.01.12
2024.01.11 TIL  (0) 2024.01.11
2024.01.10 TIL  (0) 2024.01.10