[TIL] QuerySelector 실행이 안됨

hanbyul.choi·2023년 5월 10일
0

[TIL]

목록 보기
1/39

현상

Element 클릭 시 숨겨진 div를 보여주는 기능 구현 과정에서 아래와 같이

document.querySelectorAll 로 원하는 Element를 가져와서

forEach 로 각각의 addEventListener를 추가했다.

이후 브라우저에서 각 Element 클릭 시 show-detail class가 toggle되지 않았다.

const details = document.querySelectorAll('.col');

details.forEach(function (detail) {
    const btn = detail.querySelector('.card');
    
    btn.addEventListener('click', function () {
        detail.classList.toggle('show-detail')
    })
})

원인

document.querySelectorAll 로 원하는 Class를 가져오는 과정에서 details를 log 로 찍어보니 길이가 0 인 비어있는 값이 출력.

처음 로딩되었을 때 listing 함수를 호출하여 Ajax 데이터를 불러오는데
listing 함수 외부에서 해당 코드를 작성하여 elements가 생성되기도 전에 Selector를 실행시켜 Class를 가져오지 못했다.

<script>
    $(document).ready(function () {
      listing();
    });

    function listing() {
      $('#cards-box').empty()
      $.ajax({
        type: 'GET',
        url: '/restaurant',
        data: {},
        success: function (response) {
          let rows = response['restaurant']
          for (let i = 0; i < rows.length; i++) {
            let name = rows[i]['name']
            let comment = rows[i]['comment']
            let category = rows[i]['category']
            let image = rows[i]['image']
            let star = rows[i]['star']
            let id = rows[i]['id']
            let address = rows[i]['address'].split("지번")[0]

            let star_image = '⭐'.repeat(star)

            let temp_html = `<div class="col">
                                <div class="card h-100">
                                  <img src="${image}" class="card-img-top">
                                  <div class="card-header">
                                    <h5 class="card-name">${name}</h5>
                                    <p>${star_image}</p>
                                    <div class="card-body">
                                      <hr/>
                                        <p class="card-category">카테고리 : ${category}</p>
                                        <p class="mycomment">한줄평 : ${comment}</p>
                                        <p class="myadrress">주소 : ${address}</p>
                                    </div>
                                  </div>
                                </div>
                              </div>`
            $('#cards-box').append(temp_html)
          }

        }
      })
    }
    
    // listing() 함수 외부에 작성
    
    const details = document.querySelectorAll('.col');
    console.log(details)
          details.forEach(function (detail) {
            const btn = detail.querySelector('.card');
            btn.addEventListener('click', function () {
              detail.classList.toggle('show-detail')

            })
          })

해결

  1. 카운터함수로 감싸서 1초 후에 동작하는지 확인.

  2. 정상동작 확인 후 listing 함수 내부에 append for문 다음에 코드 배치하여 해결.

느낀점

  1. 원하는 기능을 가져와 조합시킬 때 동기적인 순서를 먼저 생각해봐야 한다.

  2. 원인을 찾지 못할 때는 정확히 어느부분에서 문제가 있는지 확인하기 위해
    단계 별로 log를 확인해서 찾아낸다.

0개의 댓글