>  기사  >  웹 프론트엔드  >  JavaScript 이벤트 스트림과 이벤트 핸들러가 무엇인지 자세히 설명합니다.

JavaScript 이벤트 스트림과 이벤트 핸들러가 무엇인지 자세히 설명합니다.

伊谢尔伦
伊谢尔伦원래의
2017-07-24 15:42:501978검색

JS와 HTML 간의 상호작용은 이벤트를 통해 이루어집니다. 이벤트는 문서나 브라우저 창 내에서 발생하는 특정 상호 작용 순간입니다. 이벤트가 발생할 때 적절한 코드가 실행되도록 리스너(또는 핸들러)를 사용하여 이벤트를 예약할 수 있습니다. 전통적인 소프트웨어 엔지니어링에서 관찰자 패턴으로 알려진 이 패턴은 페이지 동작과 페이지 모양 간의 느슨한 결합을 지원합니다.

이벤트 흐름

이벤트 흐름은 페이지에서 이벤트가 수신되는 순서를 설명합니다.

이벤트 버블링

이벤트는 처음에 가장 구체적인 요소(문서에서 가장 깊은 중첩 수준을 가진 노드)에 의해 수신된 다음 덜 구체적인 노드(문서)로 위쪽으로 전파됩니다. 다음 HTML 페이지를 예로 들어 보겠습니다. 페이지에서 버튼을 클릭하면 f83a72b083183cd7ada5c1ff71f3c3ad, fb7c46738f7eaafbabf38c5f68099cb3, < 즉, 이벤트 캡처는 이벤트가 문서 객체에서 이벤트의 실제 대상 요소까지 DOM 트리를 따라 아래쪽으로 전파되는 것을 의미합니다.

DOM 이벤트 흐름

"DOM 레벨 2 이벤트"에서 지정하는 이벤트에는 이벤트 캡처 단계, 대상 단계 및 이벤트 버블링 단계의 세 단계가 포함됩니다. 가장 먼저 일어나는 일은 이벤트를 가로챌 수 있는 기회를 제공하는 이벤트 캡처입니다. 그런 다음 실제 대상이 이벤트를 수신합니다. 마지막 단계는 이벤트에 응답할 수 있는 버블링 단계입니다.

여전히 이전 버튼 클릭을 예로 들면 DOM 이벤트 흐름에서 캡처 단계 동안 "클릭" 이벤트는 문서에서 시작하여 본문 요소로 전달됩니다(실제 대상 버튼은 수신되지 않습니다). 캡처 단계 중 이벤트). 대상 단계에서 버튼 요소는 "클릭" 이벤트를 수신합니다. 마지막으로 버블링 단계에서 이벤트가 문서로 다시 전파됩니다.

이벤트 핸들러

이벤트는 사용자나 브라우저 자체가 수행하는 특정 작업이며, 이벤트에 응답하는 함수를 이벤트 핸들러 또는 이벤트 리스너라고 합니다.

HTML 이벤트 핸들러

여기서 HTML 이벤트 핸들러는 속성(attribute)을 통해 HTML 요소에 직접 정의된 이벤트 핸들러를 의미하는데, 아래 코드 예시를 참고하세요. 이 경우 이벤트 핸들러는 요소의 속성 값을 캡슐화하는 함수를 생성하며 이 값은 이벤트의 대상 요소와 동일합니다. 이런 방식으로 이벤트 처리기를 지정하면 몇 가지 단점이 있으므로 권장되지 않습니다.


<button onclick="alert(&#39;HaHa~&#39;)">Btn-1</button>
<button onclick="alert(&#39;event.type&#39;)">Btn-2</button>
<button onclick="handler()">Btn-3</button>
<script type="text/javascript">
 function handler() {
  alert("Haha~");
 }
</script>

DOM 레벨 0 이벤트 핸들러

JS를 통해 이벤트 핸들러를 지정하는 전통적인 방법은 이벤트 핸들러 속성에 함수를 할당하는 것입니다. 아래 코드 예제를 참조하세요. 이 방식으로 지정된 이벤트 핸들러는 요소의 범위 내에서 실행되며 이는 현재 요소를 참조합니다. 이러한 방식으로 추가된 이벤트 핸들러는 이벤트 흐름의 버블링 단계에서 처리됩니다. 이벤트를 삭제하려면 onclick 값을 공백으로 설정하면 됩니다.


var btn = document.getElementById("myBtn");
btn.onclick = function() {
 console.log("this.id"); // "myBtn"
};
// 删除事件处理程序
btn.onclick = null;

DOM2 레벨 이벤트 핸들러

"DOM2 레벨 이벤트"는 이벤트 핸들러 addEventListener() 및 RemoveEventListener()를 지정하고 제거하는 두 가지 메소드를 정의합니다. 이 두 가지 방법은 모든 DOM 노드에 포함되어 있습니다. 두 메소드 모두 처리할 이벤트, 처리 함수, 부울 값이라는 3개의 매개변수를 받습니다. 최종 부울 값은 true인 경우 캡처 단계에서 이벤트 핸들러가 호출되고, 버블링 단계에서 이벤트 핸들러가 호출되는 경우 false임을 의미합니다. DOM0 수준 메서드와 마찬가지로 여기에 추가된 이벤트 핸들러도 연결된 요소의 범위에서 실행됩니다. DOM2 수준 메서드를 사용하여 이벤트 핸들러를 추가하면 여러 이벤트 핸들러를 추가할 수 있다는 장점이 있습니다. 이러한 이벤트 핸들러는 추가된 순서대로 실행됩니다. 다음은 코드 예시입니다.


var btn = document.getElementById("myBtn");
// 添加,触发点击事件时先输出"myBtn"再输出"HaHa~"
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.addEventListener("click", function() {
 console.log("HaHa~");
}, false);

addEventListener()를 통해 추가된 이벤트는 RemoveEventListener()를 통해서만 제거할 수 있습니다. 삭제 시 전달된 매개변수는 추가 시 사용된 매개변수와 일치해야 합니다. 이는 addEventListener()를 통해 추가된 익명 함수는 삭제할 수 없음을 의미합니다. 추가 시 전달된 익명 함수는 삭제 시 동일한 함수를 작성하더라도 새 익명 함수일 뿐입니다. 아래 코드 예제를 참조하세요.


var btn = document.getElementById("myBtn");
// 无法删除匿名函数
btn.addEventListener("click", function() {
 console.log(this.id);
}, false);
btn.removeEventListener("click", function() {
 console.log(this.id);
}, false);

// 正确的添加和删除方式
function handler() {
 console.log(this.id);
}
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只在需要在事件到达目标之前截获它的时候才将事件处理程序添加到捕获阶段。JS高级程序设计上给出的建议是,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。

IE事件处理程序

IE实现了与DOM中类似的两个方法: attachEvent()和deleteEvent()。这两个方法接收两个参数,事件处理程序名称和事件处理程序。注意,第一个参数是事件处理程序名称而不是事件名称,也就是说在注册点击事件的处理程序时应该传入”onclick”而不是”click”,这里跟DOM的方法有些差别。另外,这两个方法注册的事件处理程序是在全局作用域中运行而不是元素作用域,this的值指向window。还有一点需要特别小心,通过attachEvent()方法也可以添加多个事件处理程序,但是它们的执行顺序却不是按照它们被添加的顺序,而是完全相反,跟DOM方法截然不同。突然觉得IE真的特别反人类~~~下面是代码示例:


var btn = document.getElementById("myBtn");
function handler1() { // ... }
function handler2() { // ... }
// 添加,触发点击事件时先执行handler2再执行handler1
btn.attachEvent("onclick", handler1);
btn.attachEvent("onclick", handler2);
// 删除
btn.deleteEvent("onclick", handler1);
btn.deleteEvent("onclick", handler2);

위 내용은 JavaScript 이벤트 스트림과 이벤트 핸들러가 무엇인지 자세히 설명합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.