> 웹 프론트엔드 > JS 튜토리얼 > 자바스크립트 이벤트 버블링과 캡처 방법 및 Blocking_javascript 기술에 대한 자세한 설명

자바스크립트 이벤트 버블링과 캡처 방법 및 Blocking_javascript 기술에 대한 자세한 설명

WBOY
풀어 주다: 2016-05-16 16:52:37
원래의
974명이 탐색했습니다.

1. 일련의 사건

이 문제의 원인은 매우 간단합니다. 다른 요소 내에 요소가 중첩되어 있다고 가정합니다.

코드 복사 코드는 다음과 같습니다. :

---------
| 요소1                                                                      | ------------------ |

--------- ---- -------

: 그리고 둘 다 onClick 이벤트 핸들러를 가지고 있습니다. 사용자가 요소 2를 클릭하면 요소 1과 요소 2 모두의 클릭 이벤트가 트리거됩니다. 그러면 어떤 이벤트가 먼저 트리거됩니까? 어떤 이벤트 핸들러 함수가 먼저 실행될까요? 즉, 사건의 정확한 순서는 무엇이었습니까?

2. 두 모델

예상대로 Netscape와 Microsoft는 "브라우저 전쟁" 시대에 대처하기 위해 매우 다른 두 가지 접근 방식을 사용했습니다.

Netscape에서는 이러한 이벤트 발생 순서를 캡처 유형이라고 합니다.

Microsoft에서는 이러한 이벤트 순서를 버블링 유형이라고 합니다. 그 중 사건의 순서는 정반대입니다. Explorer 브라우저는 버블링 이벤트만 지원하며 Mozilla, Opera7 및 Konqueror는 둘 다 지원합니다. 이전 Opera와 iCab은

을 지원하지 않습니다.


3. 이벤트 캡처

캡처 이벤트 사용 시


코드 복사

코드는 다음과 같습니다. ---------------| |------
| 요소1 | --- --------| ----------- |
|요소2 / |
| -- ---------- |
| 이벤트 캡처 중 |
---------------------------- -- ------

: 요소 1의 이벤트 핸들러가 먼저 트리거되고, 요소 2의 이벤트 핸들러가 마지막으로 트리거됩니다.


4. 버블링 이벤트

버블링 이벤트 사용 시

코드 복사

코드는 다음과 같습니다. ---------------| |------| 요소1 | - ----------|----------- |
|요소2 | ----------- |
| 이벤트 버블링 |
--------------- -------

: 요소 2의 처리 기능이 먼저 트리거되고 그 다음 요소 1이 실행됩니다.


5. W3C 모델

W3c는 이번 전투에서 현명하게 올바른 솔루션을 선택했습니다. w3c 이벤트 모델에서 발생하는 모든 이벤트는 먼저 대상 요소에 도달할 때까지 캡처 단계에 들어간 다음 버블링 단계에 들어갑니다

코드 복사


코드는 다음과 같습니다.

                                              -
| |-------| -| |
|element2 / |
|
| W3C 이벤트 모델 |
----------------------------------------- ------

웹 개발자로서 이벤트 처리 기능을 캡처 단계에서 바인딩할지 아니면 버블링 단계에서 바인딩할지 선택할 수 있습니다. 이는 마지막 매개변수인 경우 addEventListener() 메서드를 통해 수행됩니다. 이 함수의 값이 true이면 캡처 단계에서 위상 바인딩 함수가, 그렇지 않으면 false가 버블링 단계에서 함수를 바인딩합니다.


코드 복사를 하고 싶다고 가정해 보세요. 코드는 다음과 같습니다.element1 .addEventListener(' click',doSomething2,true)
element2.addEventListener('click',doSomething,false)

사용자가 요소 2를 클릭하면 다음은 어떻게 되나요?

(이곳의 이벤트는 마치 관광객이 외부에서 내부로 이동하며 점차적으로 촉발된 주요 요소에 접근한 후 반대 방향으로 떠나는 것과 같습니다.)

1. 클릭 이벤트는 먼저 캡처 단계에 들어갑니다(점차적으로 요소 2의 방향으로 접근). 캡처 단계에서 요소 2의 조상 요소에 onclick 핸들러가 있는지 확인합니다

2. 요소 1에 onclick 핸들러가 있는 것으로 확인되었으므로 doSomething2가 실행됩니다

3. 이벤트는 대상 자체(요소 2)를 확인합니다. ), 그러나 캡처 단계에는 onclick 핸들러가 없습니다. 더 많은 처리 기능을 발견했습니다. 이벤트가 버블링 단계에 진입하기 시작하며 요소 2의 버블링 단계에 바인딩된 함수인 doSomething()이 자연스럽게 실행됩니다.

4. 이벤트는 버블링 단계 동안 상위 요소에 바인딩된 핸들러가 있는지 확인하기 위해 요소 2에서 멀어집니다. 그런 경우가 없어서 아무 일도 일어나지 않습니다
반대의 경우는



코드 복사코드는 다음과 같습니다. element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)
이제 사용자가 요소 2를 클릭하면 다음과 같은 일이 발생합니다.

1. 이벤트를 클릭하여 캡쳐 단계로 들어갑니다. 캡처 단계에서 요소 2의 상위 요소에 onclick 핸들러가 있는지 확인하고 아무것도 찾지 못했습니다.
2. 이벤트가 대상 자체를 감지합니다. 이벤트가 버블링 단계에 들어가기 시작하고 요소 2의 버블링 단계에 바인딩된 함수가 실행됩니다. doSomething()3. 이벤트가 대상에서 멀어지기 시작합니다. 버블링 단계 중에 요소 2의 조상 요소에 핸들러 함수가 바인딩되어 있는지 확인합니다. 하나가 발견되었으므로 doSomething2()입니다. 요소 1이 실행됩니다.


6. 호환성 및 기존 모드

w3c dom(Document Object Model)을 지원하는 브라우저에서 전통적인 이벤트 바인딩 방법은

코드 복사

코드는 다음과 같습니다. element1.onclick = doSomething2;는 기본적으로 버블링 단계에 바인딩된 것으로 간주됩니다
7. 버블링 이벤트를 활용하세요

의식적으로 버블링 이벤트나 캡처 이벤트를 사용하는 개발자는 거의 없습니다. 오늘날 그들이 만드는 웹 페이지에서는 이벤트가 버블링되기 때문에 여러 기능으로 처리할 필요가 없습니다. 그러나 때때로 사용자는 마우스를 한 번만 클릭한 후에 많은 일이 발생하기 때문에 종종 혼란스러워합니다(버블링으로 인해 여러 기능이 실행됨). 대부분의 경우 여전히 처리 기능이 서로 독립적이기를 원합니다. 사용자가 요소를 클릭할 때 발생하는 작업과 사용자가 다른 요소를 클릭할 때 발생하는 작업은 서로 독립적이며 버블링으로 연결되지 않습니다.

8. 늘 일어나는 일입니다

가장 먼저 이해해야 할 것은 이벤트 캡처 또는 버블링이 항상 발생한다는 것입니다. 전체 페이지 문서에 대한 일반적인 onclick 처리 기능을 정의하면

코드를 복사하세요

코드는 다음과 같습니다document.onclick = doSomething;if (document.captureEvents) document.captureEvents(Event.CLICK);

페이지의 요소를 클릭하는 클릭 이벤트는 결국 페이지의 가장 높은 문서 레이어까지 버블링되어 이전 처리 기능이 버블링이 종료되었음을 명시적으로 지적하지 않는 한 일반 처리 기능을 트리거합니다. 전체 문서 수준으로 전파


위 코드의 두 번째 문장에 추가:

>>> 먼저 IE에 대해 이야기해보겠습니다
object.setCapture() 객체가 setCapture일 때 해당 메소드는 캡처를 위해 전체 문서에 상속됩니다.
문서 전체를 캡처하기 위해 메소드를 상속받을 필요가 없을 때는 object.releaseCapture()를 사용하세요
>>>기타
Mozilla도 비슷한 기능이 있지만 메소드가 약간 다릅니다
window.captureEvents(Event.eventType)
window.releaseEvents(Event.eventType)
>>>예

코드 복사 코드는 다음과 같습니다.
//다음 문장만 있는 경우 obj를 클릭할 때만 클릭이 발생합니다. obj.onclick = function(){alert(" Something")}
//다음 문장을 추가하면 메서드가 문서(또는 창, 브라우저마다 다름)에 상속되어
obj.captureEvents(Event.click); //FFobj.setCapture() // IE

9. 사용법

모든 이벤트 전파는 페이지 문서(이 최상위 수준)에서 종료되므로 다음과 같은 페이지가 있다고 가정하면 기본 이벤트 핸들러가 가능해집니다.


코드 복사 코드는 다음과 같습니다.
---------------------------- ---- --------
| 문서                                                  | 요소 2 | ----- |

------ --------------------------------- -
element1.onclick = doSomething;
element2.onclick = doSomething;
document.onclick = defaultFunction;



이제 사용자가 요소 1이나 요소 2를 클릭하면 doSomething()이 실행됩니다. 원하는 경우 이벤트가 defaultFunction()까지 버블링되는 것을 원하지 않으면 여기에서 이벤트가 버블링되는 것을 방지할 수 있습니다. 그러나 사용자가 페이지의 다른 곳을 클릭하면 defaultFunction()이 계속 실행됩니다. 이 효과는 때때로 유용할 수 있습니다.

설정 페이지 - "드래그 효과" 스크립트에 필요한 더 큰 트리거 영역을 갖도록 처리 기능을 활성화합니다. 일반적으로 요소 레이어에서 mousedown 이벤트가 발생한다는 것은 해당 요소가 선택되어 mousemove 이벤트에 응답할 수 있음을 의미합니다. 브라우저 버그를 피하기 위해 일반적으로 mousedown은 이 요소 레이어에 바인딩되지만, 다른 두 가지의 이벤트 기능 범위는 전체 페이지(?)여야 합니다.

브라우저학의 첫 번째 법칙을 기억하세요. 어떤 일이든 일어날 수 있으며, 이때 최소한 어느 정도 준비가 되어 있어야 합니다. 따라서 사용자가 드래그 앤 드래그를 할 때 페이지에서 마우스를 크게 움직이지만 스크립트가 큰 진폭에 응답하지 못하여 마우스가 더 이상 요소 레이어에 머물지 않는 경우가 발생할 수 있습니다.

1. onmouseover 핸들러 함수가 요소 레이어에 바인딩된 경우 이 요소 레이어는 더 이상 마우스 움직임에 반응하지 않으므로 사용자가 이상하게 느낄 수 있습니다.

2. onmouseup 핸들러 함수가 요소 레이어에 바인딩된 경우 , 이벤트가 트리거될 수 없습니다. 결과적으로 사용자가 이 요소 레이어를 드롭하려고 하면 요소 레이어가 계속해서 마우스 움직임에 반응합니다. 이로 인해 더 많은 혼란(?)이 발생하게 됩니다

이 예에서는 이벤트 버블링이 매우 유용합니다. 핸들러 함수를 페이지 수준에 배치하면 해당 함수가 항상 실행될 수 있기 때문입니다.


10. 꺼두세요(이벤트 버블 방지용)

그러나 일반적으로 기능이 서로 방해하지 않도록 버블링과 캡처를 모두 끄는 것이 좋습니다. 또한 문서 구조가 매우 복잡한 경우(많은 테이블이 서로 중첩되어 있는 경우 등) 시스템 리소스를 절약하기 위해 버블링을 해제할 수 있습니다. 이 시점에서 브라우저는 대상 요소의 모든 조상을 검사하여 핸들러 기능이 있는지 확인해야 합니다. 아무도 못찾아도 지금 검색하는데 시간이 많이 걸리네요 Microsoft 모델에서는 이벤트의 cancelBubble 속성을 true로 설정해야 합니다


코드 복사

코드는 다음과 같습니다. 다음:window.event.cancelBubble = true
w3c 모델에서는 이벤트의 stopPropagation() 메소드를 호출해야 합니다
코드 복사 코드는 다음과 같습니다. :
e.stopPropagation()

이렇게 하면 모든 버블이 외부로 전파되는 것을 방지할 수 있습니다. 크로스 브라우저 솔루션으로서 다음을 수행해야 합니다.
코드 복사 코드는 다음과 같습니다.

doSomething(e) 함수

{
  if (!e) var e = window.event;

e.cancelBubble = true;

if (e.stopPropagation) e.stopPropagation();

}

cancelBubble 속성을 지원하는 브라우저에서 cancelBubble을 설정해도 아무런 해가 없습니다. 브라우저는 어깨를 으쓱하고 이 속성을 생성합니다. 물론 이것이 실제로 버블링을 취소하지는 않지만 최소한 이 명령이 안전하고 올바른지 보장합니다

11.현재대상

이전에 본 것처럼 이벤트는 target 또는 srcElement 속성을 사용하여 이벤트가 발생한 대상 요소(즉, 사용자가 처음 클릭한 요소)를 나타냅니다. 우리의 경우에는 요소 2를 클릭했기 때문에 요소 2입니다.

캡처 또는 버블링 단계 중 대상 요소는 변경되지 않고 항상 요소 2와 연결되어 있다는 점을 이해하는 것이 매우 중요합니다.

그러나 다음 함수를 바인딩한다고 가정해 보겠습니다.

코드 복사 코드는
element1입니다. onclick = doSomething;

element2.onclick = doSomething;


사용자가 요소 2를 클릭하면 doSomething()이 두 번 실행됩니다. 하지만 어떤 html 요소가 이 이벤트에 응답하는지 어떻게 알 수 있나요? target/srcElement도 아무런 단서를 제공하지 않지만 사람들은 이벤트의 원인이기 때문에(사용자가 클릭한 요소이기 때문에) 항상 요소 2를 선호합니다.
이 문제를 해결하기 위해 w3c는 이벤트를 처리하는 요소를 가리키는 currentTarget 속성을 추가했습니다. 이것이 바로 우리에게 필요한 것입니다. 불행히도 Microsoft 모델에는 유사한 속성이 없습니다
"this" 키워드를 사용할 수도 있습니다. 위의 예에서는 currentTarget과 같이 이벤트를 처리하는 html 요소와 동일합니다.

12. Microsoft 모델 문제

그러나 Microsoft 이벤트 바인딩 모델을 사용하는 경우 this 키워드는 HTML 요소와 동일하지 않습니다. Lenovo에는 currentTarget 속성(?)과 유사한 Microsoft 모델이 없습니다. 위 코드를 따른다면 다음을 의미합니다:

코드 복사 코드는 다음과 같습니다.
element1.attachEvent('onclick',doSomething)

element2.attachEvent('onclick',doSomething)


어떤 HTML 요소가 이벤트 처리를 담당하는지 정확히 알 수 없습니다. 이는 Microsoft 이벤트 바인딩 모델의 가장 심각한 문제입니다. 이것이 제가 Windows에서 IE 전용 애플리케이션을 개발할 때에도 절대 사용하지 않는 이유이기도 합니다

곧 currentTarget과 유사한 속성을 추가할 수 있기를 바랍니다. 아니면 표준을 따르겠습니까? 웹 개발자에게는 이 정보가 필요합니다

후기:

실제로 자바스크립트를 사용해 본 적이 없기 때문에 이 글에서 잘 이해가 안 되는 부분이 있어서 드래그 효과에 대한 부분 등 뜬금없이 번역할 수 밖에 없습니다. 질문이 있으면 나에게 메시지를 남겨주세요. 지원해 주셔서 감사합니다!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿