웹 구성 요소 외부의 클릭을 감지하는 방법
예를 들어 버튼을 클릭할 때 일부 콘텐츠를 표시한 다음 사용자가 구성 요소 내부를 클릭할 때는 숨기고 구성 요소 외부를 클릭하면 숨길 수 있습니다.
문제
요소가 Shadow DOM에 있는지 Light DOM에 있는지에 따라 이벤트가 다르게 처리되는 방식을 고려할 때 간단해 보이는 문제가 더 복잡해집니다.
위의 예에서 사용된 다음 구성요소 정의를 사용하십시오.
<my-component>
#shadow-root
<button>Open</button>
<button>Button A</button>
<slot><slot>
<button>Button B</button>
</my-component>
원하는 동작은 다음과 같습니다.
첫 번째 시도는 다음과 같이 구성 요소 내부에 정의된 이벤트 리스너를 추가하는 것입니다.
document.addEventListener('click', (event) => {
if (event.target !== this) {
this.close();
}
});
event.target !== this
외부를 클릭하면 구성 요소가 닫힙니다. event.target === this
를 클릭하면 구성 요소가 닫히지 않습니다. event.target === this
구성 요소가 닫히지 않습니다. event.target !== this
내부의 버튼 B를 클릭하면 구성 요소가 닫힙니다. 그런데 왜
event.target === this
가 Shadow DOM 내부의 요소에 대한 것이지만 Light DOM 내부의 요소에는 해당되지 않습니까?이벤트 리타게팅
Shadow DOM 내부 요소의 경우 이벤트는 자동으로 부모 구성 요소로 대상이 변경됩니다. 이는
event.target
가 Shadow DOM 내부에서 발생하는 모든 이벤트의 상위 구성 요소로 설정됨을 의미합니다.그러나 구성 요소 내부에만 투영되고 물리적으로 이동되지 않는 Light DOM의 요소의 경우
event.target
가 요소 자체로 설정된 상태로 유지됩니다.그렇다면 구성 요소의 Light DOM에 있는 요소가 클릭되었는지 어떻게 알 수 있습니까?
해결책
event.composedPath()
메서드는 원래 요소에서 DOM 트리의 맨 위에 있는 Window
객체까지 이벤트가 통과한 각 요소를 보여줍니다. 이는 투영된 DOM 트리에서 작동하므로 요소가 DOM에서의 물리적 위치가 아니라 렌더링될 때 표시되는 순서대로 포함됩니다.document.addEventListener('click', (event) => {
console.log(event.composedPath());
/*
this will log an array containing the following
when a button in the Shadow DOM is clicked:
0: button.A
1: div#container
2: document-fragment
3: my-component <--
4: body
5: html
6: document
7: Window
and the following when a button in the Light DOM is clicked:
0: button.B
1: slot
2: div#container
3: document-fragment
4: my-component <--
5: body
6: html
7: document
8: Window
*/
});
두 경우 모두 구성된 경로에
my-component
가 나타나는 것을 볼 수 있습니다. 이 사실을 사용하여 이벤트 리스너를 다음으로 업데이트할 수 있습니다.document.addEventListener('click', (event) => {
if (!event.composedPath().includes(this)) {
this.close();
}
});
composedPath()
외부를 클릭하면 구성 요소( this
)가 포함되지 않으므로 구성 요소가 닫힙니다. composedPath()
를 클릭하면 구성 요소가 닫히지 않도록 this
가 포함됩니다. composedPath()
에 this
가 포함되어 구성 요소가 닫히지 않습니다. composedPath()
내부의 버튼 B를 클릭하면 구성 요소가 닫히지 않도록 this
가 포함됩니다. 🎆 빙고
composedPath()
는 이벤트가 시작된 곳을 확인하는 데 필요한 모든 정보를 제공합니다!할 수 있습니다view a full code example of the above component here.
Subscribe to my mailing list to be notified of new posts about Web Components and building performant websites
Reference
이 문제에 관하여(웹 구성 요소 외부의 클릭을 감지하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lamplightdev/how-to-detect-clicks-outside-of-a-web-component-4cll텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)