TIL

6월 6일 TIL - 자바스크립트 댓글 삭제 기능 오류 (1)

양죠니 2023. 6. 6. 23:09

영화검색 페이지 팀 프로젝트에서 댓글 삭제 기능 구현 도중 발생한 오류 정리하기

 

이런식으로 댓글이 입력되면 삭제하기 버튼을 눌러 삭제가 되는 기능을 추가해야 했다.

 

 

let template = `<div class="comment" style="border: 1px solid black">
                        <p>${commentObj[i].name} <span>${score}</span>
                        <span>${commentObj[i].time}</span></p>
                        <p>${commentObj[i].content}<p>
                        <button type="button" class="deleteBtn">삭제하기</button>
                    </div>   
    `;

삭제하기 버튼의 클래스 명을 deleteBtn으로 넣어주었고

 let deleteBtn = document.querySelector(".deleteBtn");
    deleteBtn.addEventListener("click", () => {
      alert("삭제합니다")
    });
  }

querySelector로 삭제버튼을 지정한 변수 deleteBtn을 만들고 버튼을 누르면 alert창이 뜨게 이벤트리스너를 추가했다.

근데 댓글이 하나만 있을땐 잘 작동을 하지만, 댓글이 두개 이상일때부터 젤 처음 입력한 댓글의 삭제하기 버튼을 눌러야만 alert창이 뜨고 나머지 댓글들의 삭제하기 버튼을 누르면 작동하지 않았다.

 

알고보니, querySeletor의 특성 때문에 젤 처음 댓글창의 버튼만 선택이 되었던 것이다. 

해당 querySelector로 선택되는 선택자가 둘 이상일때엔 젤 처음의 요소만 선택을 한다. 

 

그래서 제일 처음의 버튼만 alert이 띄워졌던 것..! 

 

제일 첫 요소의 삭제버튼 말고도 다른 삭제버튼을 누를때마다 alert창을 띄워야 하는데,,,

삭제하기 버튼을 눌렀을때의 해당 댓글의 상위태그를 선택할 수 있으면 될 것 같았다. 

나는 젤 위의 코드와 같이 template 변수에 html 태그들을 작성해 

document.getElementById("comments-list").insertAdjacentHTML("beforeend", template);

위 코드로 작성에 작성한 template 을 inserAdjacentHTML 메서드를 활용해서 화면에 추가해주었다.

 

이런 방식으로 하면 댓글을 전체 감싸주는 comment 클래스의 div태그를 선택 할 수 없었다. 삭제버튼이 눌렸을때 그 버튼이 포함되어있는 해당 댓글 전체의 div 태그를 선택하기 위해선, createElement를 사용하면 될 것 같았다.

⭐️ 왜냐하면 createElement로 태그를 생성하면 해당 태그를 변수에 넣어 지칭 할 수 있기 때문에 !! ⭐️

 

1. 각 댓글의 테두리(상위태그)가 될 createElement로 div 태그를 생성해주고 

2. template(class명이 comment인 div 태그를 제외한)을 1번에서 생성한 div태그에 넣어주고

3. 댓글 전체를 담을 comments-list에 template을 넣어주면 될 것 같았다. 

 

 let commentDiv = document.createElement("div");
 commentDiv.className = "comment";
 let template = `
                    <p>${commentObj[i].name} <span>${score}</span>
                    <span>${commentObj[i].time}</span></p>
                    <p>${commentObj[i].content}<p>
                    <button type="button" class="deleteBtn">삭제하기</button>
                      
    `;
commentDiv.append = template;
document.getElementById("comments-list").append(commentDiv);

 

호기롭게 작성을 했는데 

위와 같이 내가 입력한 태그들까지 화면에 보였다.

template 변수 안에 html 태그를 넣었기 때문에 commentDiv.append를 해서 넣어줘야 하는게 아니라 commentDiv.innerHTML로 작성해야했는데 그냥 냅다 append로 넣어줘서 저렇게 나왔던 것

 

commentDiv.innerHTML = template;
document.getElementById("comments-list").append(commentDiv);

다시 잘 작성하니

화면에 잘 나타난다..@ !!

 

이제 각 댓글의 div를 선택할 수 있게 돼, 삭제하기 버튼만 잘 구현하면 될 것 같다.

 

let deleteBtn = commentDiv.querySelector(".deleteBtn");
deleteBtn.addEventListener("click", () => {
alert(commentObj[i].password);
});

commentDiv.innerHTML = template;
document.getElementById("comments-list").append(commentDiv);

처음엔 신난 마음에 이렇게 작성했는데 ,, 적어놨던 댓글들 다 삭제되고 콘솔창에

이렇게 에러가 났다

 

아 진짜 지긋지긋한 저 에러.. 오늘 몇번 본 건지 ㅎ ㅠ 뭔가 맥락상 deleteBtn이 만들어지기 전에 쿼리셀렉터로 집고 이벤트리스너를 줘서 그런 것 같다.

    commentDiv.innerHTML = template;
    document.getElementById("comments-list").append(commentDiv);

    let deleteBtn = commentDiv.querySelector(".deleteBtn");
    deleteBtn.addEventListener("click", () => {
      alert(commentObj[i].password);
    });

위치 바꿔주고 버튼 불러와서 이벤트 주니까 잘 된다.. 휴