,
이전과 동일한 핸들러가 있지만 이번에는 몰입 단계입니다. 차단이 작동하는 것을 보려면 그 안에 있는 요소를 클릭하십시오.
핸들러는 FORM → DIV → P의 하향식 순서로 작동합니다.
JS 코드는 다음과 같습니다.
varelems = document.querySelectorAll("양식,div,p"); // 각 요소에서 가로채기 단계에서 핸들러를 걸 것입니다. for (var i = 0; i< elems.length; i++) {
elems[i].addEventListener("click", highlightThis, true);
}
다음과 같이 두 단계 모두에 핸들러를 할당하는 것을 귀찮게 하는 사람은 아무도 없습니다.
varelems = document.querySelectorAll("양식,div,p"); (변수 i = 0; 나는< elems.length; i++) {
elems[i].addEventListener("click", highlightThis, true);
elems[i].addEventListener("click", highlightThis, false);
}
내부 요소를 클릭하십시오.
이벤트가 전달되는 순서를 보려면:
FORM → DIV → P → P → DIV → FORM이어야 합니다. 요소
두 단계 모두에 참여할 것입니다.
결과
- 이벤트가 발생하면 이벤트가 발생한 요소가 event.target으로 표시됩니다.
- 이벤트는 먼저 문서 루트에서 event.target으로 이동하여 addEventListener(…., true)를 통해 제공되는 핸들러를 호출합니다.
- 이벤트는 addEventListener(…., false)를 통해 제공된 핸들러를 호출하는 방식을 따라 event.target에서 문서의 시작 부분까지 이동합니다.
각 핸들러는 이벤트 속성에 액세스할 수 있습니다.
- event.target은 이벤트가 실제로 발생한 가장 깊은 요소입니다.
- event.currentTarget(=this)은 이 순간자체 처리기가 작동했습니다(이벤트가 "도달"됨).
- event.eventPhase - 이벤트 핸들러가 실행한 단계(dive = 1, float = 3).
버블링은 event.stopPropagation() 메서드를 호출하여 중지할 수 있지만 예기치 않은 목적으로 이벤트가 필요할 수 있으므로 권장하지 않습니다.
이제 이벤트 객체로 작업할 때 버블링 및 가로채기, 이벤트 위임과 같은 고급 기능을 살펴보겠습니다.
이벤트 버블링
여러 개의 중첩 블록이 있다고 상상해보십시오.
가장 안쪽 블록을 클릭하면 이벤트가 클릭 시먼저 발생하고 해당 태그에 도달할 때까지 부모, 부모의 부모 등에서 발생합니다. 신체그리고 태그에 HTML(그러면 문서그리고 전에 창문).
내부 블록을 클릭하면 모든 외부 블록을 동시에 클릭하기 때문에 이것은 논리적입니다.
다음 예제에서 이를 살펴보겠습니다. 3개의 블록이 있으며 각 블록에는 onclick 이벤트가 첨부되어 있습니다.
가장 안쪽에 있는 빨간색 블록을 클릭하면 빨간색 블록의 onclick이 먼저 작동한 다음 파란색 블록, 녹색 블록이 어떻게 작동하는지 확인할 수 있습니다.
이 동작을 표면화이벤트 - 바닥에서 기포가 상승하는 것과 유사합니다. 거품과 마찬가지로 내부 요소를 클릭하면 상위 블록에서 트리거될 때마다 맨 위로 떠 있는 것처럼 보입니다.
이벤트.타겟
div와 이 div 내부에 있는 단락 p의 두 가지 요소가 있다고 가정해 보겠습니다. onlick을 디바에 묶자:
이 div를 클릭하면 단락으로 이동하거나 이 단락이 존재하지 않는 곳으로 이동할 수 있습니다.
이것이 어떻게 가능합니까? 다음 예를 보십시오. 녹색은 div이고 파란색은 단락입니다.
녹색 부분을 클릭하면 div를 클릭하고 파란색 부분을 클릭하면 단락에서 먼저 클릭이 발생한 다음 div에서 클릭이 발생합니다. 그러나 onclick은 div에 특별히 첨부되어 있기 때문에 일반적으로 단락의 존재를 인식하지 못할 수 있습니다.
그러나 때때로 클릭이 div 또는 하위 단락에서 직접 발생했는지 알고 싶습니다. Event 객체와 그 속성이 이를 도와줄 것입니다. 이벤트.타겟- 클릭이 발생한 요소를 정확히 저장합니다.
다음 예에서 우리는 div, 그 안에 거짓말 피, 그리고 그 안에 - 기간.
onclick 이벤트를 최상위 요소(div)에 바인딩하고 다른 요소(div, p, span)를 클릭해 보겠습니다. 사용하여 이벤트.타겟이벤트가 발생한 맨 아래 요소를 가져오고 tagName을 사용하여 이름을 표시합니다.
예를 들어 범위를 클릭하면 이벤트가 div를 포착하지만(결국 onclick이 여기에 첨부됨) 이벤트.타겟정확히 거짓말을 할 것이다 기간:
다른 블록을 클릭하면 결과가 표시됩니다.
상승 중단
따라서 모든 이벤트가 맨 위에 표시된다는 것을 이미 알고 있습니다(최대 HTML 태그그런 다음 문서로 이동한 다음 창으로 이동). 때때로 이 상승을 멈출 필요가 있습니다. 이는 이벤트가 팝업되는 모든 요소에서 수행할 수 있습니다. 이렇게 하려면 요소 코드에서 메서드를 호출합니다. event.stopPropagation().
다음 예에서 빨간색 블록을 클릭하면 자체적으로 작동한 다음 파란색 블록에서 작동합니다. 파란색 블록은 더 이상 상승을 멈추고 녹색 블록은 어떤 식으로든 반응하지 않습니다.
빨간색 블록을 클릭하면 결과가 표시됩니다.
담금
이벤트의 버블링 외에도 잠수(과학에 따르면 차단 단계). 즉, 이벤트가 먼저 위에서 아래로 이동하고(차단 단계), 요소에 도달한 다음(목표 단계), 그 다음에야 떠다니기 시작합니다(버블링 단계).
차단 단계를 고려하여 이벤트 핸들러를 중단할 수 있습니다. 추가 이벤트 리스너. 이를 위해 세 번째 매개변수가 있습니다. true이면 차단 단계에서 이벤트가 발생하고, false이면 버블링 단계에서 발생합니다(기본값).
Vargreen = document.getElementById("녹색"); green.addEventListener("클릭", func, true); 기능(이벤트) ( )
속성을 사용하여 이벤트가 발생한 단계를 확인할 수 있습니다. 이벤트.eventPhase. 1 - 차단 단계, 2 - 목표 단계, 3 - 상승 단계의 값을 사용할 수 있습니다.
위임 소개
상황을 상상해보십시오. 울여러 리. 다음 이벤트가 각 li에 첨부됩니다. li를 클릭하면 끝에 "!"가 추가됩니다.
위의 사항을 구현해 봅시다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
var li = document.querySelectorAll("#ul li"); // 루프에서 우리는 각 li에 addSign 함수를 걸고: for (var i = 0; i
li를 클릭하면 끝에 "!"가 추가되는 것을 볼 수 있습니다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
이제 ul 끝에 새 버튼이 추가되는 버튼도 있습니다. 리"항목"이라는 텍스트와 함께. 우리는 깜짝 놀랐습니다: 첨부된 이벤트가 작동하지 않습니다 새로운리! 다음을 확인합시다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
버튼을 클릭하여 li를 추가한 다음 이 새 li에서 - 반응하지 않습니다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
리 추가
문제를 해결하려면 새 li를 만들 때 함수를 걸어두십시오. 추가 서명 addEventListener를 통해. 이것을 구현해보자:
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
var li = document.querySelectorAll("#ul li"); (변수 i = 0; 나는
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
리 추가
문제를 해결하는 두 번째 방법인 이벤트 위임이 있습니다. 분석해 보겠습니다.
이벤트 위임
위임의 본질은 다음과 같습니다. 우리는 각 리가 아니라 부모에게 이벤트를 걸 것입니다. 울.
동시에 스크립트의 성능이 유지되어야 합니다. 이전과 같이 li를 클릭하면 스크립트 끝에 "!"가 추가됩니다. 새 버전의 이벤트만 ul:
var ul = document.getElementById("ul"); //ul 이벤트 중단: ul.addEventListener("click", addSign); 함수 addSign() ( )
어떻게 할까요? 이벤트가 ul에 걸려 있기 때문에 함수 내에서 li를 잡을 수 있습니다. 이벤트.타겟. event.target이 무엇인지 상기시켜 드리겠습니다. 이것은 정확히 클릭이 발생한 태그입니다. 우리의 경우에는 다음과 같습니다. 리.
위임을 통한 문제의 해결책은 다음과 같습니다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
코드 실행 결과:
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
이 경우 솔루션이 자동으로 작동합니다. 새로운 리에게도, 이벤트가 li가 아니라 ul에 매달려 있기 때문에:
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
var ul = document.getElementById("ul"); ul.addEventListener("클릭", addSign); function addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; ) //새 li를 추가하기 위한 버튼 구현: var button = document.getElementById("button"); button.addEventListener("클릭", addLi); 함수 addLi() ( var li = document.createElement("li"); li.innerHTML = "new li"; ul.appendChild(li); )
버튼을 클릭하여 li를 추가한 다음 이 새 li에 대해 다음과 같이 반응합니다.
- 단락 1
- 포인트 2
- 포인트 3
- 포인트 4
- 포인트 5
리 추가
우리의 코드는 작동하지만 결함이 없는 것은 아닙니다. 이러한 단점을 분석하고 보다 보편적인 솔루션을 작성해 보겠습니다.
일반 이벤트 위임
코드의 단점은 li 내부에 일부 중첩 태그가 있을 때 나타납니다. 우리의 경우에는 태그를 지정합니다. 나:
이 경우 를 누르면 나에 느낌표가 추가됩니다. i 태그의 끝, 태그가 아님 리, 우리가 원하는 대로(기울임꼴 외부의 li를 클릭하면 모든 것이 정상입니다):
- 절 기울임꼴 1
- 절 기울임꼴 2
- 절 기울임꼴 3
- 절 기울임꼴 4
- 절 기울임꼴 5
var ul = document.getElementById("ul"); ul.addEventListener("클릭", addSign); 함수 addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; )
기울임꼴을 클릭하면 "!" 끝에 추가됩니다(기울임꼴 외부를 누르면 잘 작동함).
문제는 다음과 같이 수정됩니다(설명된 방법이 유일한 방법은 아니지만 가장 간단함). 가장 가까운 방법을 사용하여 다음과 같이 event.target의 부모인 가장 가까운 li를 찾습니다. event.target.closest("리").
작동 방식: 클릭이 켜져 있는 경우 나, 다음에서 이벤트.타겟이것은 내가 거짓말을 하고 event.target.closest("리")- 이벤트가 발생해야 하는 우리의 리.
클릭이 리, 다음에서 이벤트.타겟, 그리고 event.target.closest("리")우리의 리는 거짓말을 할 것입니다.
점검 해보자:
- 절 기울임꼴 1
- 절 기울임꼴 2
- 절 기울임꼴 3
- 절 기울임꼴 4
- 절 기울임꼴 5
var ul = document.getElementById("ul"); ul.addEventListener("click", function(event) ( var li = event.target.closest("li"); if (li) ( //부모 li가 전혀 없는지 확인 li.innerHTML = li.innerHTML + "!"; ) )));
코드 실행 결과:
중첩이 아무리 깊어도: 태그 나태그에있을 수 있습니다 비, 그리고 태그에 있는 기간그리고 나서야 리- 그것은 중요하지 않습니다 : 건설 event.target.closest("리")모든 중첩 수준에서 부모를 찾습니다.
이벤트가 발생하면 핸들러가 먼저 중첩된 요소 자체에서 실행된 다음 상위 요소에서 실행된 다음 중첩 체인 위쪽에서 실행됩니다.
예를 들어, 각각에 핸들러가 있는 3개의 중첩 요소 FORM > DIV > P가 있습니다.
코드:
버블링은 내부의 클릭을 보장합니다.
onclick 핸들러(있는 경우)를 먼저 호출합니다. ![](https://i0.wp.com/likbezz.ru/small/vsplytie-sobytiya-javascript-1196.png)
따라서 위의 예에서 P를 클릭하면 경고가 순차적으로 표시됩니다. p → div → form.
이 과정을 버블링이라고 합니다. 마치 공기 방울이 물에 뜨는 것처럼 이벤트가 내부 요소에서 부모를 통해 위로 버블링되기 때문입니다.
이벤트.타겟
이벤트를 포착하는 요소가 무엇이든 항상 정확히 어디에서 이벤트가 발생했는지 알 수 있습니다.
이벤트를 발생시키는 가장 깊은 요소를 "target" 또는 "source" 요소라고 하며 event.target으로 사용할 수 있습니다.
이것과의 차이점(=event.currentTarget):
- event.target은 이벤트가 발생한 소스 요소이며, 버블링 프로세스 동안 변경되지 않습니다.
- 이것은 버블링이 도달한 현재 요소이며 핸들러가 현재 이 요소에서 실행 중입니다.
예를 들어 form.onclick 핸들러가 하나만 있는 경우 양식 내부의 모든 클릭을 "캐치"합니다. 내부 클릭이 있는 곳마다 - 요소에 팝업됩니다.
div(여백-하단: 10px; )
이제 일부 JavaScript - 여기에서는 텍스트 필드가 비어 있는지 여부를 테스트하는 onsubmit 이벤트 핸들러(제출 이벤트가 제출될 때 양식에서 시작됨) 내부에서 매우 간단한 검사를 구현합니다. 그렇다면 이벤트 객체에서 preventDefault() 함수를 호출하여 양식 제출을 중지한 다음 양식 아래 단락에 오류 메시지를 표시하여 사용자에게 무엇이 잘못되었는지 알려줍니다.
Const 양식 = document.querySelector("양식"); const fname = document.getElementById("fname"); const lname = document.getElementById("이름"); const para = document.querySelector("p"); form.onsubmit = function(e) ( if (fname.value === "" || lname.value === "") ( e.preventDefault(); para.textContent = "두 이름을 모두 입력해야 합니다! "; ) )
분명히 이것은 매우 약한 양식 유효성 검사입니다 - 예를 들어 필드에 공백이나 숫자를 입력하여 사용자가 양식의 유효성을 검사하는 것을 중지하지는 않지만 예를 들면 괜찮습니다.출력은 다음과 같습니다.
이벤트 버블링 및 캡처
여기서 다룰 마지막 주제는 자주 접하게 되지는 않지만 이해하지 못한다면 정말 고통스러울 수 있습니다. 이벤트 버블링 및 캡처는 동일한 이벤트 유형의 두 핸들러가 한 요소에서 활성화될 때 어떤 일이 발생하는지 설명하는 두 가지 메커니즘입니다. 이 작업을 더 쉽게 하기 위해 예제를 살펴보겠습니다. show-video-box.html 예제를 새 탭(및 다른 탭)에서 엽니다. 아래에서 실시간으로 볼 수도 있습니다.
숨겨진 비디오 예
비디오 상자 예 표시
이것은 a )가 흐름 콘텐츠의 일반 컨테이너임을 보여주고 숨기는 매우 간단한 예입니다. CSS를 사용하여 스타일을 지정할 때까지 콘텐츠나 레이아웃에 영향을 주지 않습니다.">
a ) 문서에 비디오 재생을 지원하는 미디어 플레이어를 포함합니다. 당신이 사용할 수있는