[특정 영역 외 클릭] event.target & event.currentTarget

hyozkim·2020년 1월 10일
6
post-custom-banner

순수 javascript 개발하면서 어렴풋이 알던 내용이지만 정확하게 몰랐던 개념 정리..

특정 영역 제외하고 클릭시 처리를 구현한다고 생각해보자.
예를 들어, 입력창 영역을 클릭하면 입력창에 포커스 되고 입력창 이외 영역 클릭시 포커스 아웃되는 그런 기능을 구현한다고 생각해보자.

event.target 와 event.currentTarget

우선, 이 두개의 차이점을 알아야 한다.
event.target = 이벤트 발생 위치 ( 지금 내가 클릭한 곳! )
event.currentTarget = 이벤트 생성 위치( 이벤트 발생시키도록 내가 지정한 곳! )

이 두가지에 대해 이해하고, 그 다음으로 이벤트 버블링 개념을 공부했다.

특정 영역 외 클릭시(body로 제어)

이 기능을 구현하기 위해서 이벤트 버블링을 사용해야 하나싶어 공부했다. 하지만 태그가 상하위 관계가 아니기 때문에 이벤트 버블링를 사용한 것은 아니다. 그럼에도 불구하고 이 기능을 위해 이벤트 버블링을 공부해서 일단 기록하고, 이 기능 또한 이벤트 버블링은 아니지만 비슷(?)하다.

(진정 이벤트 버블링을 보고 싶으면, 캡틴 판교님 블로그를 보면 좋을듯!

나는 아래 소스 span 태그에서 display = "none"을 시키기 위해 querySelectorAll을 사용했다.

특정 영역 클릭시

<div class="review_contents write">
  <!-- [D] review_write_info 클릭 시 자신을 숨기고 review_textarea 에 focus를 보낸다. -->
  <a href="#" class="review_write_info">
    <span class="middot">
      실 사용자의 리뷰는 상품명의 더 나은 서비스 제공과 다른 사용자들의 선택에 큰 도움이 됩니다.
    </span><br>
    <span class="middot">
      소중한 리뷰에 대한 감사로 네이버페이 포인트 500원을 적립해드립니다.
    </span>
    <span class="left_space">(단, 리뷰 포인트는 ID 당 1일 최대 5건까지 지급됩니다.)</span>
  </a>
  <textarea cols="30" rows="10" class="review_textarea"></textarea>
</div>
/***
 * 텍스트 영역 클릭 시 (div)
 * @type {Element}
 */
var reviewWriteDiv = document.querySelector(".review_contents");
reviewWriteDiv.addEventListener('click', clickContentEvent);

function clickContentEvent(event) { // 이벤트 버블링 기술 이용
    // console.log(event.target);
    // console.log(event.currentTarget);
    event.currentTarget.querySelector(".review_write_info").style.display = "none";
    event.currentTarget.querySelectorAll("span").forEach( span => {
        span.style.display = "none";
    });
    event.currentTarget.querySelector(".review_textarea").focus();
}

특정 영역 외 클릭시

event.target으로 분별한다. 아까 그 특정 영역이면 return; 으로 패스!
return; 트랩을 모두 지나치면 특정 영역에 입력창 위에 아닌 다른 div를 만들어뿐다.

/***
 * 텍스트 외 영역 클릭 시 (body)
 * @type {HTMLBodyElement}
 */
var body = document.querySelector("body");
body.addEventListener('click', clickBodyEvent);

function clickBodyEvent(event) {
    var target = event.target;
    // console.log(target);

    // 1. review_write_info 영역 이면 pass
    if(target == event.currentTarget.querySelector(".review_write_info") )
        return ;
    // 2. review_write_info 영역 내 span이면 pass
    var spanTags = event.currentTarget.querySelector(".review_write_info").querySelectorAll("span");
    for(var i=0; i<spanTags.length; i++) {
        if( spanTags[i] == target ) return ;
    }
    // 3. review_textarea 영역이면 pass
    if( target == event.currentTarget.querySelector(".review_textarea") )
        return;

    var reviewWriteInfo = event.currentTarget.querySelector(".review_write_info");
    reviewWriteInfo.style.display = "block";
    reviewWriteInfo.querySelectorAll("span").forEach( spanTag => {
        spanTag.style.display = "block";
    });
}

target 비교 시 사용한 '==' & '===' 의 차이점도 알아보자.

'==='은 엄격한 비교! 타입까지 꼼꼼히 모두 비교한다.
'=='은 비교적 헐렁한 비교다.


이번 것을 구현하면서 또 삽질을 많이했다. 삽질 하면서 그래도 알게된 이벤트 버블링, 언제 쓰게 될지 모르겠지만 알게 된 것으로 감사하다. 이벤트 위임, 이벤트 캡처 기능에 대해서 추가적으로 공부하자.

profile
차근차근 develog
post-custom-banner

1개의 댓글