JavaScript 이벤트 에이전트 가 주의해 야 할 부분

form 에 있 는 button 요소 바 인 딩 이벤트 가 발생 하면 form 의 submit 행 위 를 촉발 할 지 고려 해 야 한 다 는 것 을 알 고 있 습 니 다.그 밖 에 다른 장소 에서 button 요소 에 사건 을 연결 합 니 다.이 사건 이 예상 치 못 한 추가 효과 가 있 을 지 걱정 하지 않 아 도 됩 니 다.자 연 스 럽 게 사건 처리 코드 를 이렇게 쓸 것 입 니 다.

var button = document.querySelector('button')
button.addEventListener('click', function (e) {
 console.log('     ')
})
당신 이 안심 하고 이렇게 쓰 는 이 유 는 이 button 요소 가 이벤트 대 리 를 사용 하지 않 았 기 때 문 입 니 다.즉,어떤 요소 의 사건 을 대리 하지 않 았 기 때 문 입 니 다.
이벤트 에이 전 트 는 하나의 요소 에 사건 을 연결 해 야 한 다 는 뜻 입 니 다.그러나 이 요 소 를 직접 연결 하 는 것 이 아니 라 이 요소 의 부모 요소 에 연결 하 는 것 입 니 다.하위 요소 의 특정한 사건(예 를 들 어 이벤트 클릭)이 실 행 될 때 부모 요소 와 같은 사건 도 실 행 됩 니 다.이때 우 리 는 부모 요소 가 하위 요소 의 사건 을 대리 한다 고 말 합 니 다.
예 를 들 어 하나의 button 요소 에 기어 아이콘 이 포함 되 어 있 습 니 다.

<button>
 <svg>
 <use xlink:href="#gear" rel="external nofollow" ></use>
 </svg>
</button>
사용자 가 톱니바퀴 아이콘 을 클릭 하면 반드시 click 이벤트 가 발생 하지만,svg 나 use 요소 에 직접 연결 하지 않 고 부모 요소 button 에 연결 합 니 다.즉:

document.querySelector('button').addEventListener('click', function (e) {
 console.log('     ')
})
이 경우 button 요 소 는 모든 하위 요소 의 click 사건 을 대리 한다 고 할 수 있 습 니 다.
그러나 이런 사건 대리 상황 이 발생 했 을 때 우 리 는 조심해 야 한다.
문 제 를 더욱 직관 적 으로 설명 하기 위해 우 리 는'아버지'요 소 를 꼭대기 층 의 document 요소 로 올 렸 다.

document.documentElement.addEventListener('click', function (e) {
 console.log('     ')
})
웹 페이지 의 임의의 위치 가 클릭 되면 document 요소 에 연 결 된 클릭 이벤트 가 발생 합 니 다.사건 이 구체 적 으로 어떤 요소 에서 발생 하 는 지 알 고 싶 으 면 사건 대상 이 제공 하 는 target 속성 을 통 해 판단 할 수 있 습 니 다.

document.documentElement.addEventListener('click', function (e) {
 console.log(e.target)
})
우 리 는 사건 이 구체 적 으로 어떤 요소 에서 발생 했 는 지 쉽게 알 수 있다.그래서 위의 예제 에서 부모 요소 document 이 버튼 이 눌 렸 을 때 뭔 가 를 하고 싶다 면 우 리 는 자 연 스 럽 게 이렇게 쓸 것 입 니 다.

document.documentElement.addEventListener('click', function (e) {
 if (e.target.tagName === 'BUTTON') {
 console.log('      ')
 }
})
이 때 문제 가 발생 했 습 니 다.단 추 는 if 조건 을 눌 렀 더 라 도 반드시 성립 되 지 않 습 니 다.즉,'단추 가 눌 렸 습 니 다'를 출력 할 수 있 는 것 은 아 닙 니 다.사용자 가 단추 의 한 위치 에서 클릭 했 기 때문에 사용자 가 클릭 한 위치 에 따라 e.target 은 다음 세 가지 상황 일 수 있 습 니 다.
BUTTON 원소SVG 원소USE 원소실제 상황 은 이렇다.

우리 의 진정한 의 도 는 버튼 을 누 르 면 버튼 의 어느 위치 든 버튼 이 누 르 는 것 으로 봐 야 한 다 는 것 이다.응,간단 해.우리 다시 고 쳐 서 이렇게 쓰 자.

document.documentElement.addEventListener('click', function (e) {
 if (['BUTTON', 'SVG', 'USE'].includes(e.target.tagName.toUpperCase())) {
 //       
 }
})
이렇게 하면 아무런 문제 도 없 을 것 같 고,확실히 목적 을 달성 할 수 있 을 것 같 지만,늘 어색해 보인다.이러한 상황 은 최상 위 document 에 있어 서 모든 하위 요소 의 상황 을 알 아야 하기 때문에 저 는 가장 가 까 운 button 요소 에 만 관심 을 가지 면 됩 니 다.
OOP 가 내부 에 포 장 된 사상 에 따 르 면 button 요소 내부 의 일 은 내부 에서 소화 해 야 한다.그 서브 요 소 는 대외 적 으로 보이 지 않 고 button 요소 자체 만 노출 해 야 한다.이 사상 과 사건 의 거품 특징 에 따라 우 리 는 비교적 좋 은 해결 방법 을 가지 게 되 었 다.button 내부 요소 의 사건 응답(사건 의 거품 포함)을 금지 하고 button 요소 자체 의 사건 발생 만 허용 하면 된다.이 목적 을 실현 할 수 있 는 두 가지 방법 이 있다.
하 나 는 CSS 를 사용 하여 button 내부 요 소 를 금지 하 는 이벤트 응답 입 니 다.

button > * {
 pointer-events: none;
}
다른 하 나 는 button 내부 요소 의 이벤트 응답 을 막 기 위해 JS 를 사용 합 니 다(이벤트 거품 포함).

document.querySelector('button > svg').addEventListener('click', function (e) {
 e.stopPropagation()
 e.preventDefault()
})

document.querySelector('button').addEventListener('click', function (e) {
 console.log(e.target.tagName)
})
이 두 가지 방식 은 모두 우리 가 기대 하 는 효과 에 도달 할 수 있다.

종합 적 으로 특정한 요 소 를 대상 으로 사건 처 리 를 할 때 이 요소 에 사건 대리 가 있 으 면 대리 하 는 하위 요 소 를 조심해 야 한다.
이상 은 자 바스 크 립 트 이벤트 에이전트 가 주의해 야 할 부분 에 대한 상세 한 내용 입 니 다.자 바스 크 립 트 이벤트 에이전트 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!

좋은 웹페이지 즐겨찾기