08.委任活動


📌 8-1活動伝播は?


イベントが発生した時点で、イベントの伝播プロセスは、キャプチャプロセス、ターゲットプロセス、バブルプロセスの3つのプロセスに分けられる.
取得
  • :親要素から子要素にイベントが伝播するプロセス
  • ターゲット:実際にイベントが発生したターゲット
  • Bubbling:イベントが子要素から親要素に伝播するプロセス

  • 📌 8-2イベント伝播プロセス


    このBenは、伝播プロセスを理解するために、各サブエレメントおよび親タグエレメントに登録されます.
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>Event</title>
    </head>
    <body>
        <ul id="ul">
            <li id="li1">1</li>
            <li id="li2">2</li>
        </ul>
        <script>
            const $ul = document.querySelector("#ul");
            const $li1 = document.querySelector("#li1");
            const $li2 = document.querySelector("#li2");
            // 부모와 자식노드에 각각 내용이 다른 이벤트를 설정한다.
            $ul.addEventListener("click", () => {
                console.log("ul 클릭 이벤트 입니다.")
            });
            // 1을 클릭하는 순간 버블링으로 인해 ul 이벤트도 같이 발생한다.
            $li1.addEventListener("click", () => {
                console.log("li 클릭 이벤트 입니다.");
            });
        </script>
    </body>
    </html>
    イベントがバブル化されたため、コンソールウィンドウには次の内容が表示されます.
    li 클릭 이벤트 입니다.
    ul 클릭 이벤트 입니다.
    イベントキャプチャも発生しましたが、コンソールウィンドウで確認できないのは、キャプチャを意識的に開いてこそ実行できるためです.
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>JS</title>
    </head>
    <body>
        <ul id="ul">
            <li id="li1">1</li>
            <li id="li2">2</li>
        </ul>
        <script>
            const $ul = document.querySelector("#ul");
            const $li1 = document.querySelector("#li1");
            const $li2 = document.querySelector("#li2");
            // 부모인 ul 태그의 캡처링 이벤트 설정
            $ul.addEventListener("click", (e) => {
                console.log(`이벤트 단계 : ${e.eventPhase}`);
                console.log(`이벤트 타깃 : ${e.target}`);
            }, { capture: true });
            // 자식인 li 태그의 이벤트 설정
            $li1.addEventListener("click", (e) => {
                console.log(`이벤트 단계 : ${e.eventPhase}`);
                console.log(`이벤트 타깃 : ${e.target}`);
            });
            $li2.addEventListener("click", (e) => {
                console.log(`이벤트 단계 : ${e.eventPhase}`);
                console.log(`이벤트 타깃 : ${e.target}`);
            });
            // 부모인 ul 태그의 이벤트 설정
            $ul.addEventListener("click", (e) => {
                console.log(`이벤트 단계 : ${e.eventPhase}`);
                console.log(`이벤트 타깃 : ${e.target}`);
            });
        </script>
    </body>
    </html>
    1または2をクリックすると、コンソールウィンドウの結果は次のようになります.
    // 1 : 이벤트 캡처링
    이벤트 단계 : 1
    이벤트 타깃 : [object HTMLLIElement]
    // 2 : 이벤트 타깃
    이벤트 단계 : 2
    이벤트 타깃 : [object HTMLLIElement]
    // 3 : 이벤트 버블링
    이벤트 단계 : 3
    이벤트 타깃 : [object HTMLLIElement]

    📌 委任8-3イベント


    イベントを管理する方法は、各ノードにイベントを登録するのではなく、親要素にイベントを登録して管理します.
  • は、すべての要素のイベントを登録する必要がないため、メモリを節約できます.
  • コードの再利用性が向上します.
  • アクティブbundlingの特性を利用します.
  • 🔥 委任されていないイベント
    <!DOCTYPE html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <title>Event</title>
    </head>
    <body>
        <!--li의 요소를 클릭했을 경우 해당 li의 이름이 h3의 텍스트로 나타난다.-->
        <ul class="animals" style="width: 400px; background-color: gold;">
            <li class="animal-li" data-animal-index="Dog">Dog</li>
            <li class="animal-li" data-animal-index="Cat">Cat</li>
            <li class="animal-li" data-animal-index="Pig">Pig</li>
            <li class="animal-li" data-animal-index="Cow">Cow</li>
        </ul>
    
        <h3 class="title"></h3>
    
        <script>
            // 모든 li 태그 요소를 가져온다.
            const $animalsLi = document.querySelectorAll(".animal-li");
            // 텍스트를 표시할 공간
            const $title = document.querySelector(".title");
            // live 객체로 오기 때문에 안전하게 배열로 변환한다.
            const list = [...$animalsLi];
            // 이벤트 핸들러 함수를 생성
            const eventHandler = (event) => {
                const name = event.target.dataset.animalIndex;
                // title의 텍스트를 설정
                $title.innerText = name;
            }
            // 각각의 노드의 이벤트를 설정
            list.forEach((node) => {
                node.addEventListener("click", eventHandler);
            });
        </script>
    </body>
    </html>
    委任イベントがない場合は、多くのイベントが登録されているため、メモリの負担がかかりません.
    🔥 委任されたイベント
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>Event</title>
    </head>
    <body>
        <ul class="animals" style="width: 400px; background-color: gold;">
            <li class="animal-li" data-animal-index="Dog">Dog</li>
            <li class="animal-li" data-animal-index="Cat">Cat</li>
            <li class="animal-li" data-animal-index="Pig">Pig</li>
            <li class="animal-li" data-animal-index="Cow">Cow</li>
        </ul>
    
        <h3 class="title"></h3>
    
        <script>
            // li의 태그들의 상위 태그 요소인 ul 태그를 가져온다.
            const $animals = document.querySelector(".animals");
            // 텍스트를 표시할 공간
            const $title = document.querySelector(".title");
            // 이벤트 위임
            $animals.addEventListener("click", (event) => {
                // 해당 이벤트를 발생한 target의 dataset만 추출
                const name = event.target.dataset.animalIndex;
                // 이벤트를 발생시킨 구간이 animal-li가 아닐경우 이벤트 종료 (예외처리)
                if(event.target.className !== "animal-li") return;
                // title의 텍스트를 설정
                $title.innerText = name;
            });
        </script>
    </body>
    </html>
    委任イベントの場合、メモリを節約しながらコードの可読性とコード長を削減し、メンテナンスに役立ちます.

    📌 8-4イベントオブジェクトの違い

  • target:現在のイベントを励起する要素
  • currentTarget:現在バインドされているイベントハンドラの要素
  • <!DOCTYPE html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <title>Event</title>
    </head>
    <body>
        <ul class="animals" style="width: 400px; background-color: gold;">
            <li class="animal-li" data-animal-index="Dog">Dog</li>
            <li class="animal-li" data-animal-index="Cat">Cat</li>
            <li class="animal-li" data-animal-index="Pig">Pig</li>
            <li class="animal-li" data-animal-index="Cow">Cow</li>
        </ul>
    
        <h3 class="title"></h3>
    
        <script>
            const $animals = document.querySelector(".animals");
            const $title = document.querySelector(".title");
            // 현재 이벤트 핸들러가 바인딩 된 요소는 $animals이므로 currentTarget은 ul 태그를 가리킨다.
            $animals.addEventListener("click", (event) => {
                // 결과 : li
                console.log(event.target);
                // 결과 : ul
                console.log(event.currentTarget);
            });
        </script>
    </body>
    </html>