이벤트 버블링 및 JavaScript 이벤트 시간 캡처(요약 공유)
이 글은 이벤트 버블링, 타임 캡쳐 등 JavaScript의 이벤트에 대한 기본 지식을 자세히 설명하고 있어 모든 분들께 도움이 되기를 바랍니다.
1. 이벤트 버블링 및 이벤트 캡처
p 요소와 같은 웹 페이지의 요소를 클릭할 때. 잘 생각해보면 우리는 이 p 요소뿐만 아니라 p를 중심으로 하는 동심원 요소(요소의 부모, 외부 body, body의 부모 요소 html, 외부 요소. 레이어 문서. 이러한 중첩된 요소 간의 이벤트 전파를 이벤트 흐름이라고 합니다.
- 1. 이벤트 버블링
- 2. 이벤트 캡처
1. 이벤트 버블링
IE의 이벤트 흐름을 이벤트 버블링이라고 합니다. DOM0을 사용하여 추가한 이벤트 핸들러는 이벤트 버블링 단계에서 처리됩니다. 예:
<html> <head> <script type="text/javascript"> window.onload = bubblingHandle; function bubblingHandle() { //内层p处理程序 document.getElementById("inner").onmousedown = function() { alert("inner p"); } //外层p处理程序 document.getElementById("outer").onmousedown = function() { alert("outerp"); } document.onmousedown = function() { alert("document"); } } --> </script> </head> <body> <p id="outer" style="background-color:black; padding: 15px;"> <p id="inner" style="background-color:white; padding: 5px;"></p> </p> </body></html>
내부 레이어의 흰색 p를 클릭하면 다음과 같이 순서대로 표시됩니다.
inner p outer p document
Event Capture
Netscape에서 제안하는 이벤트 흐름을 이벤트 캡처라고 하는데, 이는 거의 반대입니다. 즉. 이벤트는 먼저 가장 덜 구체적인 요소에 의해 수신된 다음 특정 노드로 전파됩니다.
2. DOM0 레벨 이벤트 처리
이벤트는 웹 페이지에서 발생하는 일부 특정 동작에 의해 트리거됩니다. 예를 들어 특정 페이지 요소에서 마우스 왼쪽 버튼을 누르거나 특정 키보드 키를 누르거나 개체가 포커스를 얻거나 잃으면 해당 이벤트가 트리거됩니다. JavaScript와 HTML 간의 상호 작용은 이벤트를 통해 이루어집니다. 이벤트 리스너를 사용하여 이벤트를 "등록"하고, 이벤트가 발생할 때 해당 코드가 실행됩니다.
DOM 레벨 0 이벤트 핸들러는 단순성과 브라우저 간 지원으로 인해 모든 브라우저에서 계속 지원됩니다.
- DOM0 수준 메서드를 통해 이벤트 핸들러 지정
- 이벤트 핸들러에서 이 내용
- DOM0 수준 메서드를 통해 이벤트 핸들러 삭제
DOM0 수준 메서드를 통해 이벤트 핸들러 지정
DOM0 수준 메서드를 통해 이벤트 핸들러 지정 방법은 매우 간단합니다. 먼저, 작동할 요소에 대한 참조를 얻은 다음 해당 요소의 해당 이벤트 핸들러 속성
에 함수를 할당합니다. (창과 문서를 포함한 각 요소에는 고유한 이벤트 핸들러 속성
이 있습니다.) 이러한 방식으로 추가된 이벤트 핸들러는 이벤트 흐름의 버블링 단계에서 처리됩니다. 事件处理程序属性
。(每个元素包括window和document都拥有自己的事件处理程序属性
。)注意,这种方法添加的事件处理程序将在事件流的冒泡阶段被处理。
有关事件处理程序属性,有以下几点需要说明:
1、事件处理程序属性全部小写,以”on”开头,后面跟事件类型:
onclick //单击鼠标 onload //图像或页面载入完成 onmouseover //将鼠标移动到某元素上面 onmousemove //移动鼠标 onfocus //对象获得焦点
2、每个元素如img、a、input、form包括window和document都拥有自己的事件处理程序属性。如:
document.getElementById("btn1").onclick //btn1上单击鼠标 document.getElementById("img1").onmouseover //鼠标移动到img1 document.getElementById("img1").onmerror //img1图像无法载入
接下来,给事件处理程序属性赋值即可完成事件处理程序方法的指定。例如,当鼠标移动到”img1”上时,弹出对话框”This is a nice pic!”:
var pic1 = document.getElementById("img1"); pic1.onmouseover = function() { alert("This is a nice pic!"); };
特别注意:如果以上代码处于文档的底部,在页面刚刚加载时,我们将鼠标移动到img1上面。有可能由于代码尚未执行,不会弹出我们设定的对话框!如今,这个延迟已经十分短暂。
事件处理程序中的this
通过DOM0级方法指定的事件处理程序,属于元素方法
<input id="btn1" type="button" value="Click Me" /> ...//省略 <script type="text/javascript"> <!-- var btn1 = document.getElementById("btn1"); btn1.onclick = function() { alert(this.id + "\n" + this.type + "\n" + this.value); }; --> </script>
pic1.onmouseover = null;
로그인 후 복사
다음으로 이벤트 핸들러 속성에 값을 할당하여 이벤트 핸들러 메서드 지정을 완료합니다. 예를 들어, 마우스를 "img1"로 이동하면 "This is a nice pic!"이라는 대화 상자가 나타납니다. pic1.onmouseover = null;
addEventListener() //指定事件处理程序
removeEventListener() //删除事件处理程序
로그인 후 복사
특별 참고 사항: 위 코드가 문서 하단에 있는 경우 페이지가 막 로드된 경우입니다. , 위의 img1로 마우스를 이동합니다. 코드가 아직 실행되지 않았기 때문에 우리가 설정한 대화 상자가 팝업되지 않을 수도 있습니다! 오늘날 이 지연은 매우 짧습니다. addEventListener() //指定事件处理程序 removeEventListener() //删除事件处理程序
this in the event handlerDOM0 레벨 메소드를 통해 지정된 이벤트 핸들러는 element 메소드
에 속합니다. 따라서 이벤트 핸들러의 this는 해당 요소를 참조합니다! 다음 예를 들어 설명하겠습니다. <input id="btn1" type="button" value="Click Me" />
...
<script type="text/javascript">
<!--
var btn1 = document.getElementById("btn1");
var handle1 = function() {
alert("handle1!");
}
var handle2 = function() {
alert("handle2!");
}
btn1.addEventListener("click", handle1, false);
btn1.addEventListener("click", handle2, false);
-->
</script>
로그인 후 복사 DOM0 수준 메서드를 통해 이벤트 핸들러 삭제이벤트 핸들러를 삭제하려면 해당 이벤트 핸들러 속성을 null로 설정하세요.
handle1!
handle2!
로그인 후 복사
element 메소드
에 속합니다. 따라서 이벤트 핸들러의 this는 해당 요소를 참조합니다! 다음 예를 들어 설명하겠습니다. <input id="btn1" type="button" value="Click Me" /> ... <script type="text/javascript"> <!-- var btn1 = document.getElementById("btn1"); var handle1 = function() { alert("handle1!"); } var handle2 = function() { alert("handle2!"); } btn1.addEventListener("click", handle1, false); btn1.addEventListener("click", handle2, false); --> </script>
handle1! handle2!
3. DOM2 수준 이벤트 처리
1. RemoveEventListener
현재 거의 모든 브라우저는 DOM0 이벤트 모델을 지원하지만 개발자는 새로운 DOM2 모델을 사용하는 것이 좋습니다. DOM2 모델과 DOM0에는 두 가지 중요한 차이점이 있습니다.
1. DOM2는 이벤트 핸들러 속성에 의존하지 않습니다. 2. 객체의 동일한 이벤트에 대해 동시에 여러 핸들러를 등록할 수 있으며 실행됩니다. 등록순으로 순차적으로 진행됩니다.DOM2는 2가지 메소드를 정의합니다:
btn1.removeEventListener("click", handle2, false);
btn1.addEventListener("click", function(){ alert("click!"); }, false); btn1.removeEventListener("click", function(){ alert("click!"); }, false); //无法取消!
attachEvent() detachEvent()
<input id="btn1" type="button" value="Click Me" /> ... <script type="text/javascript"> <!-- var btn1 = document.getElementById("btn1"); var handle1 = function() { alert("handle1!" + "\n" + (this === window)); }; var handle2 = function() { alert("handle2!"+ "\n" + (this === window)); }; btn1.attachEvent("onclick", handle1); btn1.attachEvent("onclick", handle2); --> </script>
btn1.addEventListener("click", function(){ alert("click!"); }, false); btn1.removeEventListener("click", function(){ alert("click!"); }, false); //无法取消!
这样是无法取消以上指定的事件处理程序的!因为上面addEventListener和removeEventListener中的2个事件处理函数虽然代码相同,实质上是2个不同的函数引用。
另外,强调一点,以上两个函数的第一个参数(要处理的事件名)是没有on前缀的。这一点和IE不同,后面会说明。
tips: IE9, Firefox, Safari, Chrome以及Opera均支持DOM2级事件处理程序。
DOM2事件处理程序中的this
DOM2事件处理程序和DOM0相同,它们的this都在其依附的元素作用域中运行。this的指代参考DOM0的示例。这里之所以要特别指出DOM2的this,是为了和IE事件处理程序进行区分。IE中事件处理程序this与事件指定方式有关。
四、IE事件处理程序及跨浏览器支持
attachEvent()与detachEvent()
IE并没有提供对W3C事件模型的支持,其实现了2个和DOM2模型类似的方法:
attachEvent() detachEvent()
这两个方法只接收2个参数:事件名称以及事件处理函数。由于IE8及更早版本只支持事件冒泡,这两个方法添加的事件处理程序会在事件冒泡阶段被执行。
和DOM2不同的是:
- 1、IE事件处理方法运行作用域为全局作用域,this指代window;
- 2、第一个参数事件名以on为前缀;
- 3、当为同一对象的相同事件指定多个处理程序时,执行顺序和DOM2相反,IE中以添加它们的相反顺序执行。
例如:
<input id="btn1" type="button" value="Click Me" /> ... <script type="text/javascript"> <!-- var btn1 = document.getElementById("btn1"); var handle1 = function() { alert("handle1!" + "\n" + (this === window)); }; var handle2 = function() { alert("handle2!"+ "\n" + (this === window)); }; btn1.attachEvent("onclick", handle1); btn1.attachEvent("onclick", handle2); --> </script>
执行结果:
handle2! true handle1! true
跨浏览器支持
虽然可以使用屏蔽浏览器差异的JS库,实际上,我们自己编写一个跨浏览器兼容的事件处理代码并不是一件困难的事情,同时更有利于我们对原生JavaScript的学习理解。我们使用一个习惯上称为EventUtil的对象来进行跨浏览器事件处理:
var EventUtil = { addEventHandler : function(element, eventType, handler) { if(element.addEventListener){ element.addEventListener(eventType, handler, flase); } else if(element.attachEvent) { element.attachEvent("on" + eventType, handler); } else { element["on" + eventType] = handler; } }, removeEventHandler : function(element, eventType, handler) { if(element.aremoveEventListener){ element.addEventListener(eventType, handler, flase); } else if(element.detachEvent) { element.attachEvent("on" + eventType, handler); } else { element["on" + eventType] = null; } } }
为了保证事件处理代码能够在大多数浏览器中一致地运行,我们这里只关注冒泡阶段。以上代码使用浏览器能力检测,首先检测是否支持DOM2级方法addEventListener和removeEventListener,如果支持则使用该方法;如果不支持该方法,检测是否是IE8级更早版本的attachEvent或detachEvent方法,若支持则使用该方法;如果对以上2种方法都不支持,则使用DOM0级方法。要注意,DOM0级对每个事件只能指定一个事件处理程序。
以上对象使用示例如下:
var btn1 = document.getElementById("btn1");var handle1 = function() { alert("handle1!" + "\n" + (this === window)); };var handle2 = function() { alert("handle2!"+ "\n" + (this === window)); }; EventUtil.addEventHandler(btn1, "click", handler1); EventUtil.addEventHandler(btn1, "click", handler2); EventUtil.removeEventHandler(btn1, "click", handler2);
五、事件对象
在触发某个事件时,会产生一个event对象。该对象中包含与事件有关的信息。例如触发事件的元素、事件的类型、与特定事件相关的如鼠标位置信息等。
- 1、DOM事件对象
- 2、IE事件对象与跨浏览器事件对象
1、DOM事件对象
不论使用DOM0级还是DOM2级方法指定事件处理程序,事件触发时都会自动将一个event对象传入事件处理程序,例如:
var btn1 = document.getElementById("btn1"); btn1.onmouseover = function(evnt) { alert(evnt.type); }var handle = function(evnt) { alert(evnt.type); }; btn1.addEventListener("click", handle, false);
以上是一个简单的event对象的示例。event对象中的type属性是一个只读字符串属性,其中包含着事件的类型。例如我们上例中的click和onmouseover。event对象中包含有大量的有关事件的属性和方法(例如event.stopPropagation()方法可用于停止事件在捕获或者冒泡阶段的继续传播,preventDefault()方法会取消阻止事件的行)在此就不一一列举了。其中常用的如下:
属性/方法 | 值类型 | 读写 | 描述 |
---|---|---|---|
currentTarget | Element | readonly | 事件处理程序当前正在处理的元素 |
target | Element | readonly | 事件的目标 |
type | String | readonly | 触发事件的类型 |
preventDefault | Function | readonly | 取消事件默认行为,如链接的默认行为就是被单击时跳转到href指定的url |
stopPropagation | Function | readonly | 取消事件进一步冒泡或捕获 |
2、IE事件对象与跨浏览器事件对象
IE事件对象
在IE中,当使用DOM0级指定事件处理程序时,event对象被认为是window的一个属性,例如获取鼠标点击坐标的代码:
var mouseLoc = function() { var loc = "x: " + window.event.screenX + "\n" + "y: " + window.event.screenY; alert(loc); };
当使用attachEvent()方法指定事件处理程序时,event对象会被作为参数传入事件处理程序,我们将以上的代码重写:
var mouseLoc = function(event) { var loc = "x: " + event.screenX + "\n" + "y: " + event.screenY; alert(loc); }; btn1.attachEvent("onclick", mouseLoc);
IE中event对象的相关属性方法:
属性/方法 | 值类型 | 读写 | 描述 |
---|---|---|---|
cancelBubble | Boolean | read/write | 默认为false,置为true时取消事件冒泡(同DOM中stopPropagation) |
returnValue | Boolean | read/write | 默认为true,设为false取消事件默认行为(同DOM中preventDefault) |
srcElement | Element | readonly | 事件目标 |
type | String | readonly | 事件类型 |
跨浏览器事件对象
解决跨浏览器问题的思路是一贯的,我们可以对浏览器进行能力检测,这里我们对上面的EventUtil对象进行扩展,对我们学习原生JS,这是一个很漂亮的对象:
var EventUtil = { addEventHandler : function(element, eventType, handler) { if(element.addEventListener){ element.addEventListener(eventType, handler, flase); } else if(element.attachEvent) { element.attachEvent("on" + eventType, handler); } else { element["on" + eventType] = handler; } }, removeEventHandler : function(element, eventType, handler) { if(element.aremoveEventListener){ element.addEventListener(eventType, handler, flase); } else if(element.detachEvent) { element.attachEvent("on" + eventType, handler); } else { element["on" + eventType] = null; } }, getEvent: function (event) { return event ? event : window.event; }, getTarget: function (event) { return event.target || event.srcElement; }, preventDefault: function (event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } }, stopPropagation: function (event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubbles = true; } }, getRelatedTarget: function (event) { if (event.relatedTarger) { return event.relatedTarget; } else if (event.toElement) { return event.toElement; } else if (event.fromElement) { return event.fromElement; } else { return null; } } }
【相关推荐:javascript学习教程】
위 내용은 이벤트 버블링 및 JavaScript 이벤트 시간 캡처(요약 공유)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

프론트 엔드 개발시 프론트 엔드 열지대 티켓 인쇄를위한 자주 묻는 질문과 솔루션, 티켓 인쇄는 일반적인 요구 사항입니다. 그러나 많은 개발자들이 구현하고 있습니다 ...

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

기술 및 산업 요구에 따라 Python 및 JavaScript 개발자에 대한 절대 급여는 없습니다. 1. 파이썬은 데이터 과학 및 기계 학습에서 더 많은 비용을 지불 할 수 있습니다. 2. JavaScript는 프론트 엔드 및 풀 스택 개발에 큰 수요가 있으며 급여도 상당합니다. 3. 영향 요인에는 경험, 지리적 위치, 회사 규모 및 특정 기술이 포함됩니다.

이 기사에서 시차 스크롤 및 요소 애니메이션 효과 실현에 대한 토론은 Shiseido 공식 웹 사이트 (https://www.shiseido.co.jp/sb/wonderland/)와 유사하게 달성하는 방법을 살펴볼 것입니다.

JavaScript를 배우는 것은 어렵지 않지만 어려운 일입니다. 1) 변수, 데이터 유형, 기능 등과 같은 기본 개념을 이해합니다. 2) 마스터 비동기 프로그래밍 및 이벤트 루프를 통해이를 구현하십시오. 3) DOM 운영을 사용하고 비동기 요청을 처리합니다. 4) 일반적인 실수를 피하고 디버깅 기술을 사용하십시오. 5) 성능을 최적화하고 모범 사례를 따르십시오.

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

동일한 ID로 배열 요소를 JavaScript의 하나의 객체로 병합하는 방법은 무엇입니까? 데이터를 처리 할 때 종종 동일한 ID를 가질 필요가 있습니다 ...

프론트 엔드에서 VSCODE와 같은 패널 드래그 앤 드롭 조정 기능의 구현을 탐색하십시오. 프론트 엔드 개발에서 VSCODE와 같은 구현 방법 ...
