찾다
웹 프론트엔드JS 튜토리얼JavaScript의 이벤트 흐름 소개

JavaScript의 이벤트 흐름 소개

Feb 14, 2021 am 10:30 AM
javascript

ㅋㅋㅋ

JavaScript의 이벤트 흐름 소개이벤트 스트림이란 무엇인가요?

이벤트 버블링 vs 이벤트 캡처

DOM 이벤트 분류DOM0 이벤트DOM2 이벤트

결론

서문
  • 이 글을 읽기 전에 먼저 JavaScript 이벤트를 살펴보는 것이 좋습니다. 물론, 이미 알고 있는 사람들에게는 루프가 필요하지 않습니다. 이 기사에서는 js의 이벤트 흐름에 대해 설명합니다.
  • Text
    • 우리 모두는 클릭, 슬라이딩 등과 같은 웹 페이지에서 특정 유형의 작업을 수행할 때 일부 해당 이벤트가 트리거된다는 것을 알고 있습니다. 우리는 또한 전체 웹 페이지가 실제로 브라우저에 의해 DOM 트리로 구문 분석된다는 것을 알고 있습니다. 노드가 이벤트를 생성하면 이벤트는 노드와 루트 노드 사이에 일정한 순서로 전파되며, 이 전파 경로를 통과하는 모든 노드는 이벤트를 수신하게 됩니다. 이 전체 프로세스를
    • DOM 이벤트 흐름
    • 이라고 합니다.
    • 이벤트란 무엇인가요?
    • js와 html의 상호작용은 실제로 "이벤트"를 통해 구현됩니다. 웹 페이지의 모든 사용자 클릭, 선택, 슬라이드 등은 모두 js 세계의 이벤트입니다.
    • 이벤트의 경우 이벤트가 발생하면 응답이 있어야 합니다. JS에서는 소위 응답이 리스너입니다. 관찰자 패턴과 마찬가지로 이벤트가 우리의 주체이고, 이벤트가 발생하면 해당 이벤트(주체)에 해당하는 모든 리스너에게 알려야 해당 응답을 수행하게 됩니다.
  • 이벤트 흐름이란 무엇인가요?

이벤트 흐름은 페이지에서 이벤트가 수신되는 순서를 설명합니다. 크게 두 가지로 나누어진다.

IE의 이벤트 버블링

넷스케이프의 이벤트 캡쳐

이벤트 버블링 vs 이벤트 캡쳐

IE가 제안하는 이벤트 흐름 모델은 이벤트 버블링, 즉 아래에서 위로(Bottom to Top)이다. , 대상에 의해 트리거된 요소는 문서 개체까지 단계적으로 위쪽으로 전파됩니다.

넷스케이프가 제안하는 이벤트 흐름 모델은 이벤트 버블링과 달리 위에서 아래로, 즉 문서 개체에서 대상 개체로 단계적으로 전파됩니다.

위는 DOM0 표준에 따른 이벤트 흐름 메커니즘입니다. 나중에 ECMAScript는 DOM2의 이벤트 흐름을 더욱 표준화했습니다. DOM2에서는 이벤트에 포함된 이벤트 흐름을 다음 세 단계로 구분합니다.

이벤트 캡처 단계(capture)

대상 단계(target)

이벤트 버블링 단계(bubble)
DOM 이벤트 분류

DOM 노드에서 이벤트가 발생하면 당연히 이에 따라 처리해야 하며 DOM 이벤트는 다음과 같이 4가지 레벨로 구분됩니다.


그 중에서 더 중요한 것은 DOM0/DOM2이므로 다음은 이에 초점을 맞춘 것입니다.

DOM0 이벤트

DOM0 레벨 이벤트는 주로 두 가지 방식으로 구현됩니다. 첫 번째는 html 태그에서 이벤트 속성의 속성 값으로 함수 이름을 직접 사용하는 인라인 모델입니다. 다음과 같습니다:

// js code// eventDOM.jsfunction btnClick() {
    console.log('Hello World')}
<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    
그러나 인라인 모델에는 명백한 단점이 있습니다. 즉, 콘텐츠(html)와 동작(js) 분리에 대한 W3C 요구 사항을 위반한다는 것입니다. 따라서 두 번째 유형인 스크립트 모델(동적 바인딩 모델)이 있습니다. 구체적인 방법은 js 스크립트를 통해 특정 DOM 노드를 선택한 후 해당 노드에 이벤트 속성과 속성값을 추가하는 것이다. 다음과 같이
    // js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {
        console.log('Hello World')}btn.onclick = btnClick
    <!-- html code -->
        
            <title>eventDOM demo</title>
        
        
            <p></p>
            <script></script>
        
  1. 클릭하면 Hello World가 표시됩니다. 문제 없습니다. 그러나 스크립트 모델에도 단점이 있습니다. 위의 HTML 코드를 기반으로 다음과 같이 약간의 js를 추가합니다.
  2. // js code// eventDOM.jslet btn = document.getElementById('btn')let btnClick = function() {
        console.log('Hello World')}let btnClick2 = function() {
        console.log('Hello World again')}btn.onclick = btnClick
    btn.onclick = btnClick2
  3. 이제 Hello World again을 클릭하면 나타나는 것을 확인했습니다. 따라서 스크립트 모델에서는 하나의 노드가 동일한 유형의 이벤트를 한 번만 추가하도록 허용하고 후속 노드는 이전 이벤트를 덮어씁니다.
  4. 마지막으로 흥미로운 예를 살펴보겠습니다.
    <!-- html code -->
        
            <title>eventDOM demo</title>
        
        
            <p>
                btn3            </p><p>
                    btn2                </p><p>
                        btn1                </p>
                
            
            <script></script>
        
    // js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.onclick = function() {
        console.log('1')}btn2.onclick = function() {
        console.log('2')}btn3.onclick = function() {
        console.log('3')}

btn3을 클릭하면 출력은 다음과 같습니다.

예상대로인데 btn1을 클릭하면 어떻게 될까요? 출력은 다음과 같습니다.

확실히 btn1에 대해 하나의 리스너만 추가한 것은 좀 이상합니다. , 왜 btn2와 btn3이 합쳐진 것처럼 느껴지나요? 그 이유는 DOM0에는 IE에서 제안한 이벤트 버블링과 Netscape에서 제안한 이벤트 캡처라는 두 가지 모델이 있지만 실제로 DOM0은 이벤트 버블링만 지원하기 때문입니다. 따라서 btn1을 클릭하는 이벤트 흐름은 다음과 같습니다.

즉, 이벤트 흐름도 btn2와 btn3을 통과하므로 이들의 이벤트 처리가 시작됩니다. 그러나 분명히 이것은 우리가 원하는 결과가 아닙니다.

DOM2 events

더 자세히 설명하면 DOM2 수준 이벤트 핸들러가 있습니다. 두 가지 메소드가 정의됩니다.

  • addEventListener() 이벤트 리스너 추가
  • removeEventListener() 이벤트 리스너 제거

두 함수 모두 아래 표에 표시된 대로 세 개의 매개변수를 갖습니다.

Parameters type Description
event String '클릭'과 같은 모니터링되는 이벤트의 이름입니다. 여기서는 "on"할 필요가 없습니다
callback function 이벤트를 트리거하기 위해 실행할 콜백 함수
useCapture Boolean(기본값:false) 이벤트가 실행되는지 여부 캡처 단계에서 처리되었습니다

DOM2 中就可以對同一個節點綁定兩個以上的同類型事件監聽器了,看看下面例子:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p></p>
        <script></script>
    
// js code// eventDOM.jslet btn = document.getElementById('btn')function hello() {
    console.log("Hello World")}function helloAgain() {
    console.log("Hello World again")}btn.addEventListener('click', hello, false)btn.addEventListener('click', helloAgain, false)

輸出如下:

解決了 DOM0 只能綁定一個同類型事件監聽器的缺點啦!值得注意的是,如果綁定同樣的監聽器兩次以上,仍然只會觸發一次。

再回到上面三個 p 的那個例子進行改寫如下:

<!-- html code -->
    
        <title>eventDOM demo</title>
    
    
        <p>
            btn3            </p><p>
                btn2                </p><p>
                    btn1                </p>
            
        
        <script></script>
    
// js code// eventDOM.jslet btn1 = document.getElementById('btn1')let btn2 = document.getElementById('btn2')let btn3 = document.getElementById('btn3')btn1.addEventListener('click', function() {
    console.log('1')}, true)btn2.addEventListener('click', function() {
    console.log('2')}, true)btn3.addEventListener('click', function() {
    console.log('3')}, true)

注意,這邊我們把 addEventListener 的第三個參數設為 true,也就是事件會在捕獲階段觸發。點擊 btn1 輸出如下:

看到順序與 DOM0 的順序反過來了。首先最外層(btn3)的節點先被觸發了,而因為第三個參數被設為 true,事件會在捕獲階段就被處理,所以輸出才會是 3,2,1。如果都是 false,就會是 1,2,3。

可見 DOM2 的事件處理機制有了更彈性的操作空間。我們也可以在不同階段綁定事件監聽器,看看下面例子:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

改變一下順序,如下:

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)

點擊 btn1 輸出如下:

注意 btn1 的輸出。雖然捕獲階段先發生了,但是因為 btn1 本身就是目標節點,所以在這種情況下,總結出規律:在目標元素上不區分冒泡還是捕獲,是根據腳本中的順序來執行。

有時候,我們希望對於某節點,不要再經過冒泡階段了,DOM2 也提供了相應函數,stopPropagation

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function() {
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

可以看到,因為我們在 btn2 的捕獲階段就阻止了 btn2 的冒泡階段,所以 btn2 在捕獲後就不再繼續執行下去,確保不會冒泡,事件流如下:

加強一下前面提到的知識點,如果是在 btn1 阻止冒泡,會變成怎樣呢?

<!-- 沿用上一段 html 代碼 -->
// js code// eventDOM.jsbtn1.addEventListener('click',function(e) {
    e.stopPropagation()
    console.log('btn1 capture')}, true)btn1.addEventListener('click',function() {
    console.log('btn1 bubble')}, false)btn2.addEventListener('click',function() {
    console.log('btn2 capture')}, true)btn2.addEventListener('click',function() {
    console.log('btn2 bubble')}, false)btn3.addEventListener('click',function() {
    console.log('btn3 capture')}, true)btn3.addEventListener('click',function() {
    console.log('btn3 bubble')}, false)

點擊 btn1 輸出如下:

雖然我們對 btn1 阻止了冒泡,但是為什麼還是輸出了 btn bubble呢?原因就是前面提到了,目標節點不區分 捕獲/冒泡 階段,但是後面也就不會繼續冒泡了,算是個比較特殊的情況,可以稍微留意下。

結語

本篇大致介紹了 js 的事件流的各種模型以及階段上的工作任務,個人認為應該還算詳細。雖然個人感覺好像對編程本身沒有太明顯的幫助,但是還是算是 js 的一個重要的知識點,學習下也沒甚麼不好。若內容有誤,還歡迎指點!

相关免费学习推荐:javascript(视频)

위 내용은 JavaScript의 이벤트 흐름 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 CSDN에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
JavaScript 엔진 : 구현 비교JavaScript 엔진 : 구현 비교Apr 13, 2025 am 12:05 AM

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

브라우저 너머 : 실제 세계의 JavaScript브라우저 너머 : 실제 세계의 JavaScriptApr 12, 2025 am 12:06 AM

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Apr 11, 2025 am 08:23 AM

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Apr 11, 2025 am 08:22 AM

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript : 웹 언어의 다양성 탐색JavaScript : 웹 언어의 다양성 탐색Apr 11, 2025 am 12:01 AM

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 진화 : 현재 동향과 미래 전망JavaScript의 진화 : 현재 동향과 미래 전망Apr 10, 2025 am 09:33 AM

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

Demystifying JavaScript : 그것이하는 일과 중요한 이유Demystifying JavaScript : 그것이하는 일과 중요한 이유Apr 09, 2025 am 12:07 AM

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

Python 또는 JavaScript가 더 좋습니까?Python 또는 JavaScript가 더 좋습니까?Apr 06, 2025 am 12:14 AM

Python은 데이터 과학 및 기계 학습에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명하며 데이터 분석 및 웹 개발에 적합합니다. 2. JavaScript는 프론트 엔드 개발의 핵심입니다. Node.js는 서버 측 프로그래밍을 지원하며 풀 스택 개발에 적합합니다.

See all articles

핫 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 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구