웹 프론트엔드 JS 튜토리얼 JS에서 이벤트 버블링 및 캡처

JS에서 이벤트 버블링 및 캡처

Nov 07, 2016 pm 05:36 PM
js

刚接触 JS 的那个时候,啥也不懂,只想着如何利用 Google、百度到的函数来解决实际的问题,不会想到去一探究竟。

渐渐的,对 JS 的语言的不断深入,有机会去了解一些原理性东西。最近在看 JQuery 源码,感触很多,总想着用原生的 JS 去实现自己的一个 JQuery 库。说实在的,JQuery 里面很多函数和思路,是千百开源工作者长期的贡献,哪能是短时间就能消化的了。

最近再次碰到 addEventListener函数(MDN 上关于 addEventListener 的介绍,很详细),由于之前并没有弄懂第三个参数的含义,要么默认值,要么手动设置成 false。这次看了不少文章,彻底把事件冒泡和捕获弄懂。

什么事件冒泡与捕获

事件冒泡与捕获是 DOM 中事件传播的两种方式,比如说对于注册了相同事件的两个 DOM 元素(简单点就是两个 div,一里一外),当点击里层 div 的时候,这两个事件谁先执行。

冒泡事件,由里向外,最里层的元素先执行,然后冒泡到外层。

捕获事件,由外向里,最外层的元素先执行,然后传递到内部。

在 IE 9 之前是只支持事件冒泡,IE 9(包括 IE 9) 之后和目前主流的浏览器都同时支持两种事件。

如何设置,只需修改 addEventListener的第三个参数,true 为捕获,false 为冒泡,默认为冒泡。

举个简单的例子,

<div>
  <span class="out">
    <span class="in"></span>
  </span>
</div>
<script type="text/javascript">
  var dom_out = document.getElementsByClassName(&#39;out&#39;)[0];
  var dom_in = document.getElementsByClassName(&#39;in&#39;)[0];
  dom_out.addEventListener(&#39;click&#39;,function(){
    alert(&#39;out&#39;);
  },false);
  dom_in.addEventListener(&#39;click&#39;,function(){
    alert(&#39;in&#39;);
  },false);
</script>
로그인 후 복사

JS에서 이벤트 버블링 및 캡처

在上面这个例子中,事件是按照冒泡来执行的,点击里层的 in,会看到先 alert 的顺序是先 "in" 后 "out",如果把事件改成捕获,alert 的顺序又不一样了。

<script type="text/javascript">
  var dom_out = document.getElementsByClassName(&#39;out&#39;)[0];
  var dom_in = document.getElementsByClassName(&#39;in&#39;)[0];
  dom_out.addEventListener(&#39;click&#39;,function(){
    alert(&#39;out&#39;);
  },true);
  dom_in.addEventListener(&#39;click&#39;,function(){
    alert(&#39;in&#39;);
  },true);
</script>
로그인 후 복사

JS에서 이벤트 버블링 및 캡처

上面这个例子是捕获事件的例子,点击 in效果是不是不一样呢?

之所以会有冒泡和捕获事件(像 IE 9 之前的浏览器不支持捕获事件,还真是反程序员),毕竟在实际中处理事情肯定有个先后顺序,要么由里向外,要么由外向里,两者都是必须的。

但有时候为了兼容 IE 9 以下版本的浏览器,都会把第三个参数设置成 false 或者默认(默认就是 false)。

进一步理解冒泡和捕获

现在已经说清楚冒泡和捕获,那么如果同时出现冒泡和捕获会出现什么结果?

原来浏览器处理时间分为两个阶段,捕获阶段和冒泡阶段,

先执行捕获阶段,如果事件是在捕获阶段执行的(true 情况),则执行;

然后是冒泡阶段,如果事件是在冒泡阶段执行的(false 情况),则执行;

来看一看例子就知道了:

<div>
  <span class="s1">s1
    <span class="s2">s2
      <span class="s3">s3
      </span>
    </span>
  </span>
</div>
로그인 후 복사

这次我们设置三个 span,分别是 s1, s2, s3,然后设置 s1,s3 为冒泡执行,s2 为捕获执行:

<script type="text/javascript">
  var s1 = document.getElementsByClassName(&#39;s1&#39;)[0];
  var s2 = document.getElementsByClassName(&#39;s2&#39;)[0];
  var s3 = document.getElementsByClassName(&#39;s3&#39;)[0];
  s1.addEventListener(&#39;click&#39;,function(){
    alert(&#39;s1&#39;);
  },false);
  s2.addEventListener(&#39;click&#39;,function(){
    alert(&#39;s2&#39;);
  },true);
  s3.addEventListener(&#39;click&#39;,function(){
    alert(&#39;s3&#39;);
  },false);
</script>
로그인 후 복사

JS에서 이벤트 버블링 및 캡처

从运行的效果来看,点击 s3,依次 alert s2 => s3 => s1,说明:

捕获事件和冒泡事件同时存在的,而且捕获事件先执行,冒泡事件后执行;

如果元素存在事件且事件的执行时间与当前逻辑一致(冒泡或捕获),则执行。

默认事件取消与停止冒泡

当然,有时候我们只想执行最内层或最外层的事件,根据内外层关系来把范围更广的事件取消掉(对于新手来说,不取消冒泡,很容易中招的出现 bug)。event.stopPropagation()(IE 中window.event.cancelBubble = true)可以用来取消事件冒泡。

有时候对于浏览器的默认事件也需要取消,这时候用到的函数则是 event.preventDefault()(IE 中window.event.returnValue = false)。

那么默认事件取消和停止冒泡有什么区别呢?我的理解:浏览器的默认事件是指浏览器自己的事件(这不废话吗),比如 a 标签 的点击,表单的提交等,取消掉就不会执行啦;冒泡则取消的是由外向里(捕获)、由里向外(冒泡),stop 之后,就不会继续遍历了。stackoverflow 上的解答

看下例子,依旧是上面那个例子,不过每个函数都加了 停止冒泡:

s1.addEventListener(&#39;click&#39;,function(e){
  e.stopPropagation();
  alert(&#39;s1&#39;);
},false);
s2.addEventListener(&#39;click&#39;,function(e){
  e.stopPropagation();
  alert(&#39;s2&#39;);
},true);
s3.addEventListener(&#39;click&#39;,function(e){
  e.stopPropagation();
  alert(&#39;s3&#39;);
},false);
로그인 후 복사

JS에서 이벤트 버블링 및 캡처

点击的结果是:当点击 s2 或 s3 的时候,都会 alert s2,点击 s1,弹出 s1。因为事件被取消的缘故,点击 s3,执行 s2后就不会在向下执行了。

在看一个 preventDefault 的例子。

<div>
  <a href="/">点我回主页</a>
</div>
<div>
  <a href="/" class="back">点我不回主页</a>
</div>
<script type="text/javascript">
  var back = document.getElementsByClassName(&#39;back&#39;)[0];
  back.addEventListener(&#39;click&#39;, function(e){
    e.preventDefault();
  });
</script>
로그인 후 복사

JS에서 이벤트 버블링 및 캡처

第二个链接是不是回不了主页,因为浏览器的默认事件被取消了。

以上所有例子请在非低版本 IE 浏览器的环境下浏览 O_o

总结

总结就补充两个兼容 IE 的函数吧:

function stopBubble(e) {
  //如果提供了事件对象,则这是一个非IE浏览器
  if ( e && e.stopPropagation )
      //因此它支持W3C的stopPropagation()方法
      e.stopPropagation();
  else
      //否则,我们需要使用IE的方式来取消事件冒泡
      window.event.cancelBubble = true;
}
//阻止浏览器的默认行为
function stopDefault( e ) {
  //阻止默认浏览器动作(W3C)
  if ( e && e.preventDefault )
      e.preventDefault();
  //IE中阻止函数器默认动作的方式
  else
      window.event.returnValue = false;
  return false;
}
로그인 후 복사


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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

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

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

JS 및 Baidu Maps를 사용하여 지도 이동 기능을 구현하는 방법 JS 및 Baidu Maps를 사용하여 지도 이동 기능을 구현하는 방법 Nov 21, 2023 am 10:00 AM

JS 및 Baidu Map을 사용하여 지도 팬 기능을 구현하는 방법 Baidu Map은 지리 정보, 위치 지정 및 기타 기능을 표시하기 위해 웹 개발에 자주 사용되는 널리 사용되는 지도 서비스 플랫폼입니다. 이 글에서는 JS와 Baidu Map API를 사용하여 지도 이동 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. 준비 바이두 맵 API를 사용하기 전에 먼저 바이두 맵 오픈 플랫폼(http://lbsyun.baidu.com/)에서 개발자 계정을 신청하고 애플리케이션을 만들어야 합니다. 생성 완료

권장 사항: 우수한 JS 오픈 소스 얼굴 감지 및 인식 프로젝트 권장 사항: 우수한 JS 오픈 소스 얼굴 감지 및 인식 프로젝트 Apr 03, 2024 am 11:55 AM

얼굴 검출 및 인식 기술은 이미 상대적으로 성숙하고 널리 사용되는 기술입니다. 현재 가장 널리 사용되는 인터넷 응용 언어는 JS입니다. 웹 프런트엔드에서 얼굴 감지 및 인식을 구현하는 것은 백엔드 얼굴 인식에 비해 장점과 단점이 있습니다. 장점에는 네트워크 상호 작용 및 실시간 인식이 줄어 사용자 대기 시간이 크게 단축되고 사용자 경험이 향상된다는 단점이 있습니다. 모델 크기에 따라 제한되고 정확도도 제한됩니다. js를 사용하여 웹에서 얼굴 인식을 구현하는 방법은 무엇입니까? 웹에서 얼굴 인식을 구현하려면 JavaScript, HTML, CSS, WebRTC 등 관련 프로그래밍 언어 및 기술에 익숙해야 합니다. 동시에 관련 컴퓨터 비전 및 인공지능 기술도 마스터해야 합니다. 웹 측면의 디자인으로 인해 주목할 가치가 있습니다.

PHP와 JS를 사용하여 주식 촛대 차트를 만드는 방법 PHP와 JS를 사용하여 주식 촛대 차트를 만드는 방법 Dec 17, 2023 am 08:08 AM

PHP와 JS를 사용하여 주식 캔들 차트를 만드는 방법 주식 캔들 차트는 주식 시장에서 흔히 사용되는 기술 분석 그래픽으로 시가, 종가, 최고가 등의 데이터를 그려서 투자자가 주식을 보다 직관적으로 이해할 수 있도록 도와줍니다. 주식의 최저 가격. 이 기사에서는 특정 코드 예제와 함께 PHP 및 JS를 사용하여 주식 캔들 차트를 만드는 방법을 설명합니다. 1. 준비 시작하기 전에 다음 환경을 준비해야 합니다. 1. PHP를 실행하는 서버 2. HTML5 및 Canvas를 지원하는 브라우저 3

주식 분석을 위한 필수 도구: PHP 및 JS를 사용하여 캔들 차트를 그리는 단계를 알아보세요. 주식 분석을 위한 필수 도구: PHP 및 JS를 사용하여 캔들 차트를 그리는 단계를 알아보세요. Dec 17, 2023 pm 06:55 PM

주식 분석을 위한 필수 도구: PHP 및 JS에서 캔들 차트를 그리는 단계를 배우십시오. 인터넷과 기술의 급속한 발전으로 주식 거래는 많은 투자자에게 중요한 방법 중 하나가 되었습니다. 주식분석은 투자자의 의사결정에 있어 중요한 부분이며 캔들차트는 기술적 분석에 널리 사용됩니다. PHP와 JS를 사용하여 캔들 차트를 그리는 방법을 배우면 투자자가 더 나은 결정을 내리는 데 도움이 되는 보다 직관적인 정보를 얻을 수 있습니다. 캔들스틱 차트는 주가를 캔들스틱 형태로 표시하는 기술 차트입니다. 주가를 보여주네요

JS와 Baidu Map을 활용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 JS와 Baidu Map을 활용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 Nov 21, 2023 am 11:11 AM

JS 및 Baidu Maps를 사용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 개요: 웹 개발에서는 지리적 위치 및 지리적 정보를 표시하기 위해 지도 기능을 사용해야 하는 경우가 많습니다. 지도에서의 클릭 이벤트 처리는 지도 기능에서 일반적으로 사용되는 중요한 부분입니다. 이 글에서는 JS와 Baidu Map API를 사용하여 지도의 클릭 이벤트 처리 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 단계: Baidu Map API 파일 가져오기 먼저 다음 코드를 통해 Baidu Map API 파일을 가져올 수 있습니다.

JS 및 Baidu Maps를 사용하여 지도 히트맵 기능을 구현하는 방법 JS 및 Baidu Maps를 사용하여 지도 히트맵 기능을 구현하는 방법 Nov 21, 2023 am 09:33 AM

JS 및 Baidu Maps를 사용하여 지도 열 지도 기능을 구현하는 방법 소개: 인터넷과 모바일 장치의 급속한 발전으로 지도는 일반적인 응용 시나리오가 되었습니다. 시각적 표시 방법인 히트맵은 데이터 분포를 보다 직관적으로 이해하는 데 도움이 될 수 있습니다. 이 기사에서는 JS 및 Baidu Map API를 사용하여 지도 히트맵 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 준비 작업: 시작하기 전에 Baidu 개발자 계정, 애플리케이션 생성, 해당 AP 획득 등의 항목을 준비해야 합니다.

PHP 및 JS 개발 팁: 주식 캔들 차트 그리기 방법 익히기 PHP 및 JS 개발 팁: 주식 캔들 차트 그리기 방법 익히기 Dec 18, 2023 pm 03:39 PM

인터넷 금융의 급속한 발전으로 인해 주식 투자는 점점 더 많은 사람들의 선택이 되었습니다. 주식 거래에서 캔들 차트는 주가의 변화 추세를 보여주고 투자자가 보다 정확한 결정을 내리는 데 도움이 되는 일반적으로 사용되는 기술적 분석 방법입니다. 이 기사에서는 PHP와 JS의 개발 기술을 소개하고 독자가 주식 캔들 차트를 그리는 방법을 이해하도록 유도하며 구체적인 코드 예제를 제공합니다. 1. 주식 캔들 차트의 이해 주식 캔들 차트를 그리는 방법을 소개하기 전에 먼저 캔들 차트가 무엇인지부터 이해해야 합니다. 캔들스틱 차트는 일본인이 개발했습니다.

js와 vue의 관계 js와 vue의 관계 Mar 11, 2024 pm 05:21 PM

js와 vue의 관계: 1. 웹 개발의 초석인 JS 2. 프론트엔드 프레임워크로서의 Vue.js의 등장 3. JS와 Vue의 상호 보완적인 관계 4. JS와 Vue의 실제 적용 Vue.

See all articles