이벤트는 JavaScript 애플리케이션의 심장이자 모든 것을 하나로 묶는 접착제입니다. 이벤트는 브라우저에서 웹 페이지와 특정 유형의 상호 작용을 수행할 때 발생합니다. 이벤트는 사용자가 무언가를 클릭하거나, 특정 요소 위로 마우스를 이동하거나, 키보드의 특정 키를 누르는 것일 수 있습니다. 이벤트는 웹 페이지 로드, 사용자 스크롤 또는 창 크기 조정과 같이 웹 브라우저에서 발생하는 것일 수도 있습니다.
JavaScript를 사용하면 특정 이벤트의 발생을 수신하고 해당 이벤트에 대한 응답으로 특정 이벤트가 발생하도록 지정할 수 있습니다.
오랜 진화의 역사 속에서 우리는 인라인 이벤트 처리 방식(HTML 요소 내에서 직접 이벤트 핸들러를 사용하는 방식)에 작별을 고했습니다. 오늘날의 이벤트는 이미 DOM의 중요한 부분입니다. 불행하게도 IE는 IE 4.0에서 처음 구현된 이벤트 모델을 계속 유지하고 있으며 후속 IE 버전에서는 크게 변경되지 않았습니다. 이는 IE가 여전히 독점 이벤트 모델( 버블 유형) 및 기타 주류 브라우저는 DOM 레벨 3 규정이 확정될 때까지 DOM 표준 이벤트 처리 모델(캡처 유형 및 버블링 유형)을 점차적으로 지원하지 않았습니다.
역사적 이유는 다음과 같습니다. W3C 사양은 DOM 레벨 1에서 어떤 이벤트도 정의하지 않았습니다. 2000년 11월에 출시된 DOM 레벨 2가 되어서야 DOM 레벨 2에서 더 자세하고 미묘한 방법이 정의되었습니다. 웹 페이지의 이벤트를 제어하기 위해 최종적으로 완전한 이벤트가 2004 DOM 레벨 3 사양으로 마무리되었습니다. IE4는 1995년에 출시되어 자체 이벤트 모델(버블 유형)을 구현했기 때문에 당시에는 DOM 표준이 전혀 없었습니다. 그러나 이후 DOM 표준 사양 프로세스에서 IE의 이벤트 모델이 흡수되었습니다.
현재 IE 브라우저 외에도 기타 주요 Firefox, Opera 및 Safari는 모두 표준 DOM 이벤트 처리 모델을 지원합니다. IE는 여전히 자체적인 이벤트 모델, 즉 버블링 유형을 사용합니다. 이벤트 모델의 일부는 DOM 표준에 의해 채택됩니다. 이는 IE에 일반적인 이벤트 처리 방법인
DOM 표준을 사용하는 것만으로도 좋습니다. 브라우저 전반에 걸쳐 효과적일 수 있습니다.
DOM(Document Object Model) 구조는 HTML 요소가 이벤트를 생성하면 해당 이벤트가 요소 노드와 루트 노드 사이에 특정 순서로 전파됩니다. 노드는 이벤트를 수신하며 이 전파 프로세스를 DOM 이벤트 흐름이라고 부를 수 있습니다.
이벤트 시퀀스에는 이벤트 캡처와 이벤트 버블링이라는 두 가지 유형이 있습니다.
이벤트 버블링
이것은 IE 브라우저의 이벤트 모델 구현이며 이해하기 가장 쉽고 적어도 더 현실적이라고 생각합니다. 버블링은 이름에서 알 수 있듯이 이벤트가 맨 위에 도달할 때까지 물 속의 거품처럼 거품을 발생시킵니다. DOM 트리 구조의 관점에서 볼 때 이벤트는 상위 노드를 따라 리프 노드에서 루트 노드까지 전달됩니다. 브라우저 인터페이스 보기 HTML 요소 배열 수준에서 이벤트는 하위 관계를 가진 가장 확실한 대상 요소에서 전달됩니다. 가장 불확실한 대상 요소입니다. 이벤트는 특정 이벤트 대상에서 시작하여 가장 불확실한 이벤트 대상까지
이벤트 캡처(Event Capturing)
Netscape 구현과 정반대입니다. DOM 트리의 최상위 요소부터 시작하여 가장 정확한 요소까지 버블링 유형 이 이벤트 모델은 개발자(적어도 나에게는...)에게 약간 혼란스럽습니다. 왜냐하면 직관적인 이해는 버블링 유형과 동일해야 하기 때문입니다. 이벤트 전달은 가장 확실한 요소인 이벤트 생성 요소부터 시작되어야 합니다.
DOM 표준 이벤트 모델
위의 두 가지 이벤트 모델을 설명하고 비교했습니다. DOM 표준은 캡처 이벤트와 버블링 이벤트라는 두 가지 이벤트 모델을 동시에 지원합니다. 그러나 캡처 이벤트가 먼저 발생합니다. 두 이벤트 스트림 모두 문서 객체에서 시작하여 문서 객체로 끝나는 DOM의 모든 객체를 트리거합니다(대부분의 표준 호환 브라우저는 계속해서 이벤트를 창 객체에 캡처/버블링합니다).
그림과 같이 먼저 캡처 이벤트 전달이 있고 그 다음 버블링 전달이 있습니다. 따라서 처리 함수가 캡처 이벤트 모니터링과 버블링 이벤트 모니터링을 모두 등록하면 DOM 이벤트 모델에 있게 됩니다. 두 번 전화했다.
DOM 표준 이벤트 모델의 가장 독특한 기능은 텍스트 노드도 이벤트를 트리거한다는 것입니다(IE에서는 아님).
이벤트 전송
DOM 표준의 이벤트 흐름 원리를 더 잘 설명하기 위해 "이벤트 전송" 요약에 넣어 보다 구체적인 설명을 제공합니다.
물론 하이퍼링크에 클릭 이벤트 리스너를 추가하면 링크를 클릭할 때 이벤트 리스너가 실행됩니다. 그러나 이벤트 리스너가 링크가 포함된 p 요소 또는 DOM 트리 상단의 문서 노드에 할당된 경우 링크를 클릭하면 이벤트 리스너도 트리거됩니다. 이는 이벤트가 트리거되는 요소에만 영향을 미치는 것이 아니라 DOM 구조를 따라 모든 요소에 영향을 미치기 때문입니다. 이를 이벤트 전달이라고 합니다.
W3C 이벤트 모델은 이벤트 전달의 원칙을 명확하게 지적합니다. 이벤트 전달은 3단계로 나눌 수 있습니다.
그림과 같이: 표준 이벤트 전달 모드
(1) 이벤트 캡처(Capturing) 단계에서 이벤트는 DOM 트리를 따라 대상 노드의 각 조상 노드로 전달됩니다. 대상 노드까지. 예를 들어 사용자가 하이퍼링크를 클릭하면 클릭 이벤트가 문서 노드에서 링크가 포함된 html 요소, body 요소 및 p 요소로 전송됩니다.
이 프로세스 동안 브라우저는 이벤트에 대한 캡처 이벤트 리스너를 감지하고 이벤트 리스너를 실행합니다.
(2) 대상 단계에서는 브라우저가 대상 이벤트에 할당된 이벤트 리스너를 찾은 후 이벤트 리스너를 실행합니다. 대상 노드는 이벤트를 트리거한 DOM 노드입니다. 예를 들어, 사용자가 하이퍼링크를 클릭하면 해당 링크는 대상 노드입니다(이 경우 대상 노드는 실제로 하이퍼링크 내의 텍스트 노드입니다).
(3) 버블링 단계에서는 이벤트가 DOM 트리로 전달되고 대상 요소의 조상 노드가 하나씩 다시 문서 노드로 방문됩니다. 모든 단계에서. 브라우저는 캡처 이벤트 리스너가 아닌 이벤트 리스너를 감지하고 실행합니다.
모든 이벤트가 버블링 단계를 거치는 것은 아닙니다
모든 이벤트가 캡처 단계와 대상 단계를 거치지만 일부 이벤트는 버블링 단계를 건너뜁니다. 예를 들어 요소가 입력 포커스를 얻도록 하는 포커스 이벤트와 요소가 입력 포커스를 잃게 만드는 흐림 이벤트는 버블링되지 않습니다.
이벤트 핸들
이벤트 핸들(이벤트 처리 함수라고도 하며 DOM에서는 이벤트 수신 함수라고 함), 이벤트에 대한 응답으로 호출되는 함수를 이벤트 처리 함수
라고 합니다. 각 이벤트는 이벤트 핸들러에 해당합니다. 프로그램이 실행되면 해당 함수나 명령문이 이벤트 핸들러에 할당됩니다. 이벤트가 발생하면 브라우저는 지정된 함수나 명령문을 실행하여 웹 페이지 콘텐츠와 사용자의 통합을 실현합니다. 운영. 브라우저는 이벤트 발생을 감지하면 해당 이벤트에 해당하는 이벤트 핸들러에 값이 할당되었는지 검색하여 해당 이벤트 핸들러를 실행합니다.
우리는 클릭 이벤트에 응답하는 함수가 onclick 이벤트 처리 함수라고 믿습니다. 이전에는 이벤트 핸들러가 JavaScript 또는 HTML의 두 가지 방식으로 할당되었습니다.
JavaScript에서 이벤트 핸들러 함수를 할당하는 경우 먼저 처리할 개체에 대한 참조를 얻은 다음 해당 이벤트 핸들러 함수 속성에 함수를 할당해야 합니다. 간단한 예를 참조하세요.
1 var link=document.getElementById("mylink");2 link.onclick=function(){3 alert("I was clicked !");4 };
우리의 관점에서 위의 예에서 우리는 이벤트 핸들러를 사용하는 것이 쉽다는 것을 알았습니다. 그러나 이벤트 핸들러 함수 이름은 소문자여야 하며 이벤트 핸들러는 요소가 로드된 후에만 요소에 할당될 수 있습니다. 예외가 되십시오.
문서 로딩 기술에 대해서는 "Window.onload 로딩을 위한 다양한 솔루션" 문서를 참조하세요.
이벤트 핸들러가 HTML에 할당된 경우 HTML 속성을 통해 직접 이벤트 핸들러 기능을 설정하고 적절한 스크립트를 속성 값으로 포함하면 됩니다. 예:
<a>......</a>
이런 종류의 JavaScript 코드와 HTML을 통해 스타일 속성은 CSS 속성을 요소에 직접 할당하는 것과 유사합니다. 이는 코드를 지저분하게 보이게 만들고 문서의 정적 콘텐츠를 표시하는 코드와 동적 동작을 구현하는 코드를 분리하는 원칙을 위반합니다. 1998년부터 이러한 글쓰기 방식은 더 이상 사용되지 않습니다.
이 전통적인 이벤트 바인딩 기술에는 분명한 장점과 단점이 있습니다.
* 간단하고 편리합니다. 처리 기능의 코드 블록을 HTML로 직접 작성하고 JS에서 해당 요소의 이벤트 속성에 값을 할당하기만 하면 됩니다.
*IE 및 DOM 표준 모두에서 지원되는 메서드는 IE 및 DOM 표준 모두에서 이벤트 버블링 프로세스 중에 호출됩니다.
*처리 펑션블록에 이벤트를 등록한 요소를 직접 참조할 수 있습니다.
*한 요소에 여러 리스너를 등록하려는 경우 이 방법을 사용할 수 없습니다.
이벤트 리스너
이제 대부분의 브라우저에는 고급 이벤트 처리 방법, 즉 이벤트 리스너가 내장되어 있습니다. 이 처리 방법은 이벤트 핸들러가 수행할 수 있는 요소에 제한이 없습니다. 구속되다.
이벤트 핸들러와 이벤트 리스너의 가장 큰 차이점은 이벤트 핸들러를 사용할 때 한 번에 하나의 이벤트 핸들러만 연결할 수 있지만 이벤트 리스너의 경우 한 번에 여러 이벤트 핸들러를 연결할 수 있다는 점을 이미 알고 있습니다.
IE의 이벤트 리스너:
IE提供的却是一种自有的,完全不同的甚至存在BUG的事件监听器,因此如果要让脚本在本浏览器中正常运行的话,就必须使用IE所支持的事件监听器。另外,Safari 浏览器中的事件监听器有时也存在一点不同。
在IE中,每个元素和window对象都有两个方法:attachEvent方法和detachEvent方法。
1 element.attachEvent("onevent",eventListener);
此方法的意思是在IE中要想给一个元素的事件附加事件处理函数,必须调用attachEvent方法才能创建一个事件监听器。attachEvent方法允许外界注册该元素多个事件监听器。
attachEvent接受两个参数。第一个参数是事件类型名,第二个参数eventListener是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象。还有一点是此方法的事件类型名称必须加上一个”on”的前缀(如onclick)。
1 element.attachEvent("onevent",eventListener);
要想移除先前元素注册的事件监听器,可以使用detachEvent方法进行删除,参数相同。
DOM标准下的事件监听器:
在支持W3C标准事件监听器的浏览器中,对每个支持事件的对象都可以使用addEventListener方法。该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。所以与IE浏览器中注册元素事件监听器方式有所不同的。
1 //标准语法 2 element.addEventListener('event', eventListener, useCapture);3 //默认4 element.addEventListener('event', eventListener, false);
addEventListener方法接受三个参数。第一个参数是事件类型名,值得注意的是,这里事件类型名称与IE的不同,事件类型名是没’on’开头的;第二个参数eventListener是回调处理函数(即监听器函数);第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用 ,通常此参数通常会设置为false(为false时是冒泡),那么,如果将其值设置为true,那就创建一个捕捉事件监听器。
移除已注册的事件监听器调用element的removeEventListener方法即可,参数相同。
1 //标准语法 2 element.removeEventListener('event', eventListener, useCapture);3 //默认4 element.removeEventListener('event', eventListener, false);
通过addEventListener方法添加的事件处理函数,必须使用removeEventListener方法才能删除,而且要求参数与添加事件处理函数时addEventListener方法的参数完全一致(包括useCapture参数),否则将不能成功删除事件处理函数。
跨浏览器的注册与移除元素事件监听器方案
我们现在已经知道,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。要确保浏览器使用正确的方法其实并不困难,只需要通过一个if-else语句来检测当前浏览器中是否存在addEventListener方法或attachEvent方法即可。
这样的方式就可以实现一个跨浏览器的注册与移除元素事件监听器方案:
1 var EventUtil = {
2 //注册
3 addHandler: function(element, type, handler){
4 if (element.addEventListener){
5 element.addEventListener(type, handler, false);
6 } else if (element.attachEvent){
7 element.attachEvent("on" + type, handler);
8 } else {
9 element["on" + type] = handler;
10 }
11 },
12 //移除注册
13 removeHandler: function(element, type, handler){
14 if (element.removeEventListener){
15 element.removeEventListener(type, handler, false);
16 } else if (element.detachEvent){
17 element.detachEvent("on" + type, handler);
18 } else {
19 element["on" + type] = null;
20 }
21 }
22 };
이벤트 개체 참조
이벤트를 더 잘 처리하기 위해 발생한 이벤트의 특정 속성에 따라 다양한 작업을 수행할 수 있습니다.
이벤트 모델과 마찬가지로 IE는 다른 브라우저와 다르게 개체를 처리합니다. IE는 개체를 처리하기 위해 event라는 전역 이벤트 개체를 사용하는 반면(전역 변수 window.event에서 찾을 수 있음), 다른 모든 브라우저는 W3C 권장 방법을 사용합니다. 이벤트 객체를 포함하는 독립적인 매개변수 전달을 사용합니다.
브라우저 전반에 걸쳐 이러한 기능을 구현할 때 가장 일반적인 문제는 이벤트 자체에 대한 참조를 얻고 이벤트의 대상 요소에 대한 참조를 얻는 것입니다.
다음 코드는 이 문제를 해결해 줍니다.
1 var EventUtil ={
2 getEvent: function(event){
3 return event ? event : window.event;
4 },
5 getTarget: function(event ){
6 return event.target || event.srcElement;
7 }
8};
"이벤트 버블링 중지" 및 "브라우저의 기본 동작 차단", 이 두 개념은 매우 중요하며 복잡한 애플리케이션 처리에 매우 유용합니다.
1. 이벤트 버블링 중지
이벤트 버블링 중지는 버블링 이벤트의 추가 전달을 중지하는 것을 의미합니다. (이벤트 전달을 취소하면 IE 및 DOM 표준에 일반적인 버블링 이벤트를 중지할 뿐만 아니라 DOM 표준 브라우저 캡처 이벤트 지원도 중지할 수 있습니다. topPropagation() 메소드를 사용하십시오). 예를 들어 위 그림의 버블링 이벤트 전달에서 본문 처리가 이벤트 전달을 중지한 후 상위 문서의 이벤트 리스너는 더 이상 알림을 받지 않고 더 이상 처리되지 않습니다.
2. 이벤트 차단의 기본 동작
이벤트 중지의 기본 동작은 일반적으로 이벤트가 전달되고 처리된 후 브라우저가 이벤트와 관련된 기본 동작(해당 동작이 있는 경우)을 실행한다는 것을 의미합니다. 예를 들어 양식의 입력 유형 속성이 "제출"인 경우 클릭 후 이벤트가 전파된 후 브라우저가 자동으로 양식을 제출합니다. 또 다른 예로, 입력 요소의 keydown 이벤트가 발생하고 처리된 후 브라우저는 기본적으로 사용자가 입력한 문자를 입력 요소의 값에 자동으로 추가합니다.
이벤트 버블링을 중지하는 방법:
IE에서는 이벤트 개체의 cancelBubble을 true로 설정하면 됩니다.
1 function someHandle() {
2 window.event.cancelBubble = true;
3}
DOM 표준은 이벤트 객체의 stopPropagation() 메서드를 호출하는 것입니다.
1 function someHandle(event) {
2 event.stopPropagation();
3}
따라서 크로스 브라우저 중지 이벤트 전달 방법은 다음과 같습니다.
1 function someHandle(event) {
2 event = event || window.event;
3 if(event.stopPropagation){
4 event.stopPropagation();
5 }else {
6 event.cancelBubble = true;
7 }
8 }
이벤트 차단의 기본 동작 처리 방법
이벤트 모델과 이벤트 객체의 차이점과 마찬가지로 이벤트의 기본 동작을 방지하는 방법도 IE와 다른 모든 브라우저에서 다릅니다.
IE에서는 이벤트 객체의 returnValue를 false로 설정하면 됩니다.
1 function someHandle() {
2 window.event.returnValue = false;
3}
DOM 표준은 이벤트 객체의 PreventDefault() 메서드를 호출하여 수행할 수 있습니다.
1 function someHandle(event) {
2 event.preventDefault();
3}
이러한 이유로 크로스 브라우저 취소 이벤트가 전달된 후 기본 처리 방법은 다음과 같습니다.
1 function someHandle(event) {
2 이벤트 = 이벤트 || window.event;
3 if(event.preventDefault){
4 event.preventDefault();
5 }else{
6 event.returnValue = false;
7 }
8 }
완료 이벤트 처리 호환성 함수
1 var EventUtil = {
2 addHandler: function(element, type, handler){
3 if (element.addEventListener){
4 element.addEventListener(type, handler, false);
5 } else if (element.attachEvent ){
6 element.attachEvent("on" + type, handler);
7 } else {
8 element["on" + type] = handler;
9 }
10 },
11 removeHandler: 함수 (요소, 유형, 핸들러){
12 if (element.removeEventListener){
13 element.removeEventListener(type, handler, false);
14 } else if (element.detachEvent){
15 element.detachEvent("on" + type, handler);
16 } else {
17 element["on" + type] = null;
18 }
19 },
20 getEvent: function(event){
21 return event ? 이벤트 : window.event;
22 },
23 getTarget: function(event){
24 return event.target || event.srcElement;
25 },
26 preventDefault: function(event){
27 if (event.preventDefault){
28 event.preventDefault();
29 } else {
30 event.re TurnValue = false;
31 }
32 },
33 stopPropagation: function(event){
34 if (event.stopPropagation){
35 event.stopPropagation();
36 } else {
37 event.cancelBubble = true;
38 }
39 };
标准事件模型为我们提供了两种方案,可能很多朋友分不清这两种不同模型有啥好处,为什么不只采取一种模型.
这里抛开IE浏览器讨论(IE只有一种,没法选择)什么情况下适合哪种事件模型。
1. 捕获型应用场합
捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,传递方式与操系统中당신의 모든 것을 완벽하게 활용하세요. ,如果注册了系统全局快捷键监听器,该事件就先被操作系统层捕获,全局监听器就先于应用程序快捷键监听器得到communication,也就是全局的先获得控控权,它有权阻止事件的进一步传递。所以捕获型事件模型适用于작전局范围内的监听, 这里的局是某个顶层结点与该结点所有子孙结点形成范围。
例如你想작품 전체局 的 点击事件监听, 同对于document结点与document下所有的子结点, 에서 某个条件下要求所有的子结点点击无效, 这种情况下冒泡模型就解决不了了,而捕获型却不常适合,可以在最顶层结点添加捕获型事件监听器,伪码如下:
1 함수 globalClickListener(event) {
2 if(canEvent 통과 == 거짓) {
3 //取消事件进一步向子结点传递和冒泡传递
4 event.stopPropagation();
5 //取消浏览器事件后的默认执行
6 event.preventDefault();
7 }
8 }
这样一来,当canEventPass条件为假时,document下所有我的子结点click注册事件都不会被浏览器处理。
2. 冒泡型의 사용 용도
우리는 보통 버블링 이벤트 모델을 사용한다고 할 수 있습니다. IE에서는 이 모델만 지원하기 때문입니다. 다시 한번 이야기해 보겠습니다. 이 모델을 적절하게 사용하면 스크립트 성능이 향상될 수 있습니다. onmousemove, onmouseover, onmouseout 등 자주 발생하는 요소 이벤트의 경우, 처리 후 해당 이벤트를 더 이상 전달할 필요가 없다는 것이 확실하다면 대담하게 취소할 수 있습니다. 또한 하위 노드 이벤트 리스너의 처리가 상위 계층 리스너의 처리에 부정적인 영향을 미칠 경우 영향을 제거하기 위해 하위 노드 리스너에서 이벤트의 추가 상향 전송도 금지해야 합니다.
2
3
4
5
다음 조각을 추가하세요.
1 var p2 = document.getElementById('p2');
2 EventUtil .addHandler(p2, 'click', function(event){
3 event = EventUtil.getEvent (event);
4 EventUtil.stopPropagation(event);
위 설명에 따라 버블 처리 중 빨간색 영역을 클릭하면 이벤트가 발생합니다. p2로 전달된 후 중지되므로 p2의 상위 요소는 알림을 받을 수 없으므로 차례로 표시됩니다.
DOM 표준을 지원하는 브라우저에서 컨테이너에 다음 코드를 추가합니다.
2 event.stopPropagation();
3}, true);위 코드의 리스닝 함수는 통과시 캡처타입이 호출되므로 빨간색 영역을 클릭한 후 , 이벤트 소스는 ID가 event_source인 요소이지만 캡처 유형은 최상위 레벨부터 시작하여 본문 노드 청취 함수가 먼저 호출되고 이벤트가 취소되고 더 전달되므로 현재만 전달됩니다. 본체가 나타납니다. 관련 권장사항:
node.js의 이벤트 처리 메커니즘에 대한 자세한 설명
javascript를 사용하여 크로스 브라우저 이벤트 처리 메커니즘 생성 [Blue-Dream 제작]_javascript 실력
위 내용은 JavaScript 이벤트 처리 메커니즘 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!