첫 소프트웨어 개발 프로젝트에서 배운 것...

그래서 현재 진행 중인 소프트웨어 개발 프로그램의 일환으로 지금까지 HTML, CSS 및 JavaScript에서 다룬 것과 관련하여 수행할 프로젝트가 주어졌습니다. 이 프로젝트에서는 우리가 만드는 앱이 HTML/CSS/JS여야 했습니다. 공용 API에서 데이터에 액세스하는 프런트 엔드. 프로그래밍 세계에 입문한지라 약간 벅찬 일이었지만 최선을 다했습니다. 여기저기서 몇 가지 문제에 부딪쳤습니다. 특히 제 코드를 디버깅하고 관심 있는 새로운 주제와 상호 작용했습니다. 그 중 하나는 동적으로 생성된 요소에 클릭 이벤트 리스너를 추가하는 방법이었습니다.

내 프로젝트를 위해 주로 API에서 데이터를 채우는 온라인 서점을 만들었습니다. 각 책마다 하트 아이콘을 배치하여 클릭 시 찜 목록에 항목을 추가하고 빨간색으로 변하도록 했습니다. 그러나 데이터를 보낼 div에 클릭 이벤트를 넣었을 때 응답하지 않았습니다.

기존 데이터의 HTML은 다음과 같습니다.

<div class="books-list">
                    <div class="book-card">
                        <img src="assets/images/480x720.jpeg" alt="book-1">
                        <div class="book-detail">
                            <h3>The Stars Below</h3>
                            <h4>by David Baldacci</h4>
                            <div class="wishlist-details">
                                <i class="fa fa-heart-o" aria-hidden="true"></i>
                                <p class="hide">Add to wish list</p>
                            </div>
                        </div>
                    </div>
          </div>


하트 아이콘을 빨간색으로 변경하고 위시리스트에 책을 추가하는 JS는 다음과 같습니다.

 const booksList = document.querySelector('.books-list');
    booksList.addEventListener('click', e => {
        if (e.target.className === 'fa fa-heart-o') {
            e.target.className = 'fa fa-heart';
        } else if (e.target.className === 'fa fa-heart') {
            e.target.className = 'fa fa-heart-o';
        }
    })


위의 코드 스니펫에서 이벤트가 아이콘이 대상인 books-list div에서 발생하는 것을 볼 수 있습니다. 그러나 로드하는 데 시간이 걸리는 비동기 함수에 의해 API에서 가져온 새로 생성된 요소에 대해서는 작동하지 않았으므로 이벤트가 대상을 찾지 못합니다.

정말 도움이 된 this post를 발견했습니다. 상위 요소에 이벤트 리스너를 추가하여 수행되는 이벤트 버블링의 사용을 제안합니다. 아이콘이 포함된 div에서만 처리되도록 하기 위해 클래스가 지정됩니다. 따라서 대신

 const booksList = document.querySelector('.books-list');


div가 있는 기본 태그에 이벤트 리스너를 배치하고 대상의 클래스를 지정했습니다. 즉

  const main = document.querySelector('main');
    main.addEventListener('click', e => {
        if (e.target.classList.contains('fa-heart-o')) {
            e.target.classList.remove('fa-heart-o');
            e.target.classList.add('fa-heart');
            e.target.nextElementSibling.classList.remove('hide');
            e.target.nextElementSibling.classList.add('hide1');
        } else if (e.target.classList.contains('fa-heart')) {
            e.target.classList.remove('fa-heart');
            e.target.classList.add('fa-heart-o');
            e.target.nextElementSibling.classList.remove('hide1');
            e.target.nextElementSibling.classList.add('hide');
        }
    })


이 수정 후 새로 추가된 각 요소에 대해 클릭 이벤트가 원활하게 응답했습니다.

좋은 웹페이지 즐겨찾기