본문 바로가기
JavaScript

[Javascript] target 속성과 closest() 함수를 조합하여 ui 선택하기

by teamnova 2023. 6. 14.
728x90

안녕하세요. 이번 시간에는 자바스크립트의 target 속성과 closest() 함수를 사용하여 동적으로 추가된 ui를 선택하는 방법을 알아보겠습니다.

 

Event 인터페이스의 target 속성은 이벤트가 발생한 대상 객체를 가리키며, closest() 함수는 현재 element에서 가장 가까운 조상을 반환합니다. 

두 가지에 대한 좀 더 자세한 내용은 링크를 참조해 주세요.

target : 

https://developer.mozilla.org/ko/docs/Web/API/Event/target

 

Event.target - Web API | MDN

Event 인터페이스의 target 속성은 이벤트가 발생한 대상 객체를 가리킵니다. 버블링과 캡처링 단계에서는 Event.currentTarget (en-US)과 다를 수 있습니다.

developer.mozilla.org

closest :

 

https://developer.mozilla.org/ko/docs/Web/API/Element/closest

 

 

위 두가지 기능을 활용하면 한 html 태그 안에 있는 다양한 요소들 중 원하는 ui를 선택할 때 비교적 간단한 코드로 구현할 수 있습니다.

 

예를 들어 아래와 같은 코드로 배열 형태의 데이터를 받아 웹 브라우저에 렌더링 해주는 코드가 있다고 가정합니다.

<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">        
    </head>        
    <style>
        .animal_container {
			/* 텍스트와 버튼의 너비 지정 */
            width : 200px;
            /* flex로 설정하여 컨테이너 형태로 가로로 배치되게 처리 */
            display: flex;
            /* 양쪽 정렬 */
            justify-content: space-between;
        }
    </style>
    <body>       
       
       	<-- 렌더링될 div 태그 -->
        <div id="animal_block"></div>            
        
        <script>
        	// div 태그에 변수 할당
            const animal_block = document.getElementById('animal_block');
            // 렌더링에 쓰일 json 데이터
            const array_data = ["사자", "호랑이", "토끼", "코끼리", "원숭이"];

			// 배열 갯수만큼 렌더링
            for (const animal of array_data) {
            	// div 태그 생성
                const div = document.createElement('div');
                // 생성된 태그에 animal_container 클래스 세팅
                div.setAttribute('class', 'animal_container')
                // 배열의 값과 선택하기 버튼 추가
                div.innerHTML = `<span>${animal}</span><button id = ${animal}>선택하기</button>`;
                animal_block.append(div);
            }
        </script>        
    </body>
</html>

만약 선택하기 버튼을 눌렀을 때 왼쪽에 있는 텍스트가 표시되도록 버튼에 이벤트를 등록하려면 for문 내부에 클릭 이벤트를 일일히 등록해야 합니다.

 

하지만 다음과 같이 target 속성과 closet 함수를 사용하면 animal_block 하나에만 클릭이벤트를 설정하여 해당 기능을 구현할 수 있습니다.

animal_block.addEventListener('click', (e) => { // animal_div 클릭 시 이벤트
    // 클릭한 지점에서 가장 가까운 요소를 반환. 만약 해당 요소가 select_btn 클래스일 경우 클릭한 div 내에 있는 button들 중 클릭 지점과 가장 가까운 button 요소 반환  
    const target = e.target.closest(".select_btn"); 
    if (!target) return; // target이 아닐 경우에는 return
})

설명하자면 먼저 특정 ui에 대한 이벤트가 아니라 animal_block이라는 내부를 클릭했을 때의 전체 범위로 클릭 이벤트를 생성합니다.

그리고 target과 closest함수를 조합하여 클릭한 곳이 .select_btn 내부일 때 가장 가까운 .select_btn의 요소를 target 변수에 할당합니다. 

만약 클릭된 target 요소가 .select_btn 내부가 아니라면 null값이 뜨면서 처음으로 return 합니다.

 

이런식으로 한 div 요소 안에 다양한 이벤트가 달려있는 ui들이 있을 경우 부모의 div 태그 전체 범위에서의 이벤트 등록만으로도 원하는 ui를 선택할 수 있습니다.

 

아래 코드는 버튼을 클릭했을 때의 이벤트를 시각적으로 표현하기 위해 선택하기 버튼을 클릭했을 때 하단에 클릭한 버튼의 텍스트가 출력되도록 수정한 전체 코드입니다.

<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">        
    </head>        
    <style>
        .animal_container {

            width : 200px;
            display: flex;
            justify-content: space-between;
        }
    </style>
    <body>       
       
        <div id="animal_block"></div>  
        
        <span id = "show_text"></span>
        
        <script>
            // 렌더링 되는 div
            const animal_block = document.getElementById('animal_block');
            // 선택하기 버튼 클릭 시 텍스트가 보여지는 div
            const show_text = document.getElementById('show_text');
            
            const json_data = ["사자", "호랑이", "토끼", "코끼리", "원숭이"];

            // 배열 갯수만큼 렌더링
            for (const animal of array_data) {
            	// div 태그 생성
                const div = document.createElement('div');
                // 생성된 태그에 animal_container 클래스 세팅
                div.setAttribute('class', 'animal_container')
                // 배열의 값과 선택하기 버튼 추가
                div.innerHTML = `<span>${animal}</span><button id = ${animal} class = "select_btn">선택하기</button>`;
                animal_block.append(div);
            }


            animal_block.addEventListener('click', (e) => { // animal_div 클릭 시 이벤트
            // 클릭한 지점에서 가장 가까운 요소를 반환. 만약 해당 요소가 select_btn 클래스일 경우 클릭한 div 내에 있는 button들 중 클릭 지점과 가장 가까운 button 요소 반환  
            const target = e.target.closest(".select_btn"); 

            if (!target) return; // target이 아닐 경우에는 return
		// 선택한 버튼의 id가 show_text가 출력
                show_text.innerHTML = target.id
            })
        
        </script>        
    </body>
</html>

 

 

결과 영상입니다.