JavaScirpt/jQuery

jQuery 7 - [이벤트 처리, 이벤트 개념, 처리, 위임, 메소드]

Tree_Park 2021. 3. 22. 13:16
728x90

이벤트 처리


코딩의 시작, TCP School


이벤트의 개념


이벤트(event) 란?

  • 마우스를 클릭한다거나, 텍스트 박스에 글을 쓰는 등의 수많은 동작들이 event를 발생시킨다.
  • 이벤트가 발생했다는 것은 웹페이에서 특정 동작이 발생하여, 웹 브라우저가 그 사실을 알려주는 것을 의미.

이벤트 핸들러(event handler)

  • 특정 요소에서 발생하는 이벤트를 처리하기 위해서는 이벤트 핸들러(event handler)라는 함수를 작성하여 연결해야만 한다.
  • 이벤트 핸들러가 연결된 특정 요소에서 지정된 타입의 이벤트가 발생하면, 웹 브라우저는 연결된 이벤트 핸들러를 실행

$(function() {
    $("button").on({ // 모든 <button> 요소에
        mouseenter: function() { // mouseenter 이벤트를 설정
            $("#text").appaend("마우스가 버튼 위로 진입<br>");
        },
        click: function() {  // click 이벤트를 설정
            $("#text").append("마우스가 버튼을 클릭<br>");
        },
        moseleave: function() { // mouseleave 이벤트를 설정
            $("#tetx").append("마우스가 버튼 위에서 빠져나감<br>");
        }
    });
});

이벤트 객체 (event object)

이벤트 핸들러 함수는 이벤트 객체(event object)를 인수로 전달받을 수 있다.

  • 이렇게 전달받은 이벤트 객체를 이용하여
    • 이벤트의 성질을 결정하거나
    • 이벤트의 기본 동작을 막을 수도 있다.

  • 제이쿼리 이벤트 객체는 W3C 표준 권고안을 따르는 이벤트 객체를 정규화한 것.

이벤트의 처리


이벤트의 연결 (event binding)

  • 특정 요소에서 발생하는 이벤트를 처리하기 위해서는 이벤트 핸들러(event handler) 함수를 작성해야 한다.
  • 작성된 이벤트 핸들러를 특정 요소에 연결하는 것 을 이벤트의 연결(event binding)이라고 한다.

이벤트 연결을 위한 다양한 방법

// 1.
$("#btn").click(fuonction(event) {// 실행하고자 하는 제이쿼리 코드 });
// 2.
$("#btn").bind("click", fuonction(event) {// 실행하고자 하는 제이쿼리 코드 });
// 3.
$("#btn").on("click", fuonction(event) {// 실행하고자 하는 제이쿼리 코드 });
// 4.
$("body").on({click: fuonction(event) {// 실행하고자 하는 제이쿼리 코드 }}, "#btn");
// 5. 
$("body").on("click", "btn", fuonction(event) {// 실행하고자 하는 제이쿼리 코드});

제이쿼리 1.7부터는 .bind()나 .click() 메소드를 사용해도 내부적으로 .on() 메소드를 이용하여 이벤트 핸들러와 연결


$(function() {
    $("body").on({    //<body> 요소에
        click: function() { // click 이벤트가 발생햇을 때
            $("#text").html("버튼을 클릭했습니다.");
        }
    }, "#btn"); // id가 "btn"인 요소에 이벤트 핸들러를 등록
});

이벤트 처리의 발 전

  • 제이쿼리 1.0에서는 .bind() 메소드를 사용하여 이벤트 핸들러를 등록
  • 그다음에는 .live() 메소드와 .delegate() 메소드를 거쳐
  • 현재는 .on() 메소드를 이용하여 이벤트를 처리

.on

  • 제이쿼리 1.7부터 소개된 .on() 의 특징

  1. 선택한 요소에 어떤 타입의 이벤트라도 연결 가능
  2. 하나의 이벤트 핸들러에 여러 개의 이벤트를 동시 연결 가능
  3. 선택한 요소에 여러 개의 이벤트 핸들러와 여러 개의 이벤트를 같이 연결 가능
  4. 사용자 지정 이벤트(custom event)를 위해 이벤트 핸들러를 데이터로 넘길 수 있다.
  5. 차후에 다루게 될 요소를 이벤트에 연결 가능

$(function() {
    // 모든 <button> 요소에 mouseenter와 mouseleave 이벤트를 설정
    $("button").on("mouseenter mouseleave", function() {
        $("#text").append("마우스가 버튼 위로 진입하거나 빠져나갔다.<br>");
    });

    // 또한 하나의 요소에 여러 개의 이벤트 핸들러를 사용하여 여러 개의 이벤트를 같이 연결 가능
    $("button").on({
        mouseenter: function() {
            $("#text").append("마우스가 버튼 위로 진입");
        },
        click: function() {
            $("#text").append("마우스가 버튼을 클릭");
        },
        mouseleave: function() {
            $("text").append("마우스가 버튼 위로 빠져나감");
        }
    });
});

.one()

  • 연결된 이벤트 핸들러가 한 번 실행되고 나서는 더는 실행되지 않는다.
  • 같은 이벤트에 대해 연결된 이벤트 핸들러가 한 번 실행된 이후에는 다른 이벤트 핸들러를 실행하고 싶을 때 사용 가능

$(function() {
    $("button").on("click", function() {
        // 모든 <button> 요소가 처음 클릭됐을 때에만 실행
        $("#text").append("첫 번째 요소가 클릭");

        // 모든 <button> 요소가 두 번째 클릭됐을 때부터는 이 이벤트 핸들러가 실행
        $(this).click(function() {
            $("#text").append("이 버튼을 이미 클릭했음");
        });
    });
});

예제 실험 해보기


.off()

더 이상 사용하지 않는 이벤트와의 연결을 제거

$(function() {
    $("#clickBtn").on("click", function() { // id가 "clickBtn"인 요소를 클릭했을 때 실행
        $("#text").append("버튼 클릭");
    });

    $("#removeBtn").on("click", function() {
        $("#clickBtn").off("click"); // id가 "clickBtn"인 요소의 클릭 이벤트와의 연결을 제거
    });
});    

이벤트의 위임


이벤트의 위임 (event delegation)

  • 제이쿼리는 이벤트의 위임을 통해 다수의 요소에 공통으로 적용되는 이벤트 핸들러를 공통된 조상 요소에 단 한 번만 연결하면 동작할 수 있도록 해준다.

a 요소에 직접 이벤트 핸들러 추가

// 요소마다 직정 등록된 이벤트 핸들러는 현재 존재하느 <a> 요소에만 연결되며, 새롭게 추가되는 요소에는 연결되지 않는다.
$(function() {
    $("ul a").on("click",  function(event) { // <ul>요소의 자식 요소 중 모든 <a>요소를 클릭했을 때,
        event.preventDefault(); // <a>요소의 클릭시 기본 동작인 링크의 작동을 중지시킴.    
        $("#text").append("이 링크는 동작하지 않습니다!<br>");
    });

    $("button").one("click",  function() {
        $("ul").append('<li><a href="/jquery/intro">jQuery</a></li>');
    });
});

이벤트의 위임 이용

$(function() {
    // 해당 요소에 첫 번째 인수로 전달받은 이벤트가 전파되었을 때,
    // 그 이벤트를 발생한 요소가 두 번째 인수로 전달받은 선택자와 같은지를 검사
    // 만약 이벤트가 발생한 요소와 두 번째 인수로 전달받은 선택자가 같으면, 연결된 이벤트 핸들러를 실행
    $("ul").on("click", "a", function(event) {
        event.preventDefatult();
        $("#text").append("이 링크는 동작하지 않습니다.<br>");
    });

    $("button").one("click", function() {
        $("ul").append('<li><a href="/jquery/intro">jQuery</a></li>');
    });

    // 이벤트의 위임을 사용하면 현재 존재하는 자손 요소 뿐만아니라, 나중에 추가되는 자손 요소까지 모두 자동으로 연결
});

이벤트의 전파 (event propagation)

이벤트의 전파

  • 이벤트의 전파란 : 이벤트가 발생했을 때, 브라우저가 이벤트 핸들러를 실행시킬 대상 요소를 결정하는 과정


  • 이벤트가 Document 객체나 HTML 문서의 요소에서 일어나면 대상 객체를 결정하기 위해 이벤트의 전파가 일어난다.

    • 이벤트가 전파되는 과정을 (event bubbling)이라고 한다.

    • 이벤트 버블링 : 이벤트가 발생한 요소부터 시작하여 DM 트리를 따라 위쪽으로 올라가며 전파되는 과정을 의미.

      • 이벤트가 발생한 요소에 연결된 이벤트 핸들러가 실행된 후, 그 부모 요소에 연결된 핸들러가 실행
      • 또다시 그 부모 요소에 등록된 핸들러가 실행되며, 마지막에는 Document 객체까지 계속 전파된다.

    • 이러한 전파를 통해 위와 같은 이벤트의 위임(event delegation)이 가능.


      더 자세한 내용 - 이벤트 리스너 호출

[이벤트 리스너 호출]
이벤트 리스너가 등록되고 해당 객체나 요소에 지정된 타입의 이벤트가 발생하면, 브라우저는 자동으로 등록된 이벤트 리스너를 호출
- 이 때 이벤트 리스너는 인수로 이벤트 객체(event object)를 전달받으며, 식별자를 통해 전달받은 이벤트 객체를 참조


[이벤트 호출 순서]

 addEventListener() 메소드를 사용하여 하나의 이벤트 타입에 여러 개의 이벤트 리스너를 등록 가능
 이 때, 특정 타입의 이벤트가 발하면 브라우저는 다음과 같은 순서로 이벤트를 호출한다.

1. 이벤트의 대상이 되는 객체나 요소에 프로퍼티로 등록한 이벤트 리스너를 가장 먼저 호출
2. 그 후, addEventListener() 메소드를 사용하여 등록한 이벤트 리스너를 등록한 순서대로 호출


[이벤트 전파]
이벤트가 발생했을 때, 브라우저가 이벤트 리스너를 실행시킬 대상 요소를 결정하는 과정

이벤트의 대상이 Window 객체와 같은 단일 객체라면 이벤트의 전파는 일어나지 않는다.
- Document객체나 HTML 문서의 요소에서 이벤트가 발생하면 대상 요소를 결정하기 위해 이벤트의 전파가 발생

이벤트의 전파 방식은 두 가지 방식으로 구분
1. 버블링(bubbling) 전파 방식
2. 캡처링(capturing) 전파 방식


[버블링 전파 방식]
이벤트가 발생한 요소부터 시작해서, DOM 트리를 따라 위쪽으로 올라가며 전파되는 방식
- 해당 요소의 리스너가 실행된 후, 그 부모 요소에 등록된 리스너가 실행된 후, 또 다시 그 부모 요소에 등록된 리스너가 실행되는 방식이다.
- 이벤트의 전파는 Document 객체뿐만 아니라 가장 마지막에는 Window 객체까지 계속 이어진다.

# 버블링 전파 방식은 다수의 요소에 공통으로 적용되는 이벤트 리스너를 각각의 요소마다 따로 등록할 필요 없이 공통된 조상 요소에 한 번만 등록하면 처리할 수 있다는 장점을 가진다.

// 각 요소마다 버블링 방식으로 click 이벤트 리스너를 등록.
document.getElementById("divBox").addEventListener("click", clickDiv);
document.getElementById("paraBox").addEventListener("click", clickPara);
document.getElementById("spanBox").addEventListener("click", clickSpan);
function  clickDiv(event) { document.getElementById("text").innerHTML  +=  "div 요소를 click 하셨네요!<br>";}
function  clickPara(event) {  document.getElementById("text").innerHTML  +=  "p 요소를 click 하셨네요!<br>";}
function  clickSpan(event) {  document.getElementById("text").innerHTML  +=  "span 요소를 click 하셨네요!<br>"; }


[캡처링 전파 방식]
이벤트가 발생한 요소까지 DOM 트리의 최상위부터 아래쪽으로 내려가면서 전파되는 방식
- Window 객체의 리스너가 실행된 후, Document 객체에 등록된 리스너가 실행되고, 또 다시 그 자식 요소에 등록된 리스너가 실행되는 방식
-  이벤트의 전파는 이벤트가 발생한 요소까지 이어진다.
- 이 전파 방식을 사용하기 위해서는 addEventListener() 메소드의 세 번째 인수에 true를 전달하면 된다.

# 캡처링 전파 방식은 실제 이벤트의 대상이 되는 요소에 이벤트가 전달되기 전에 상위 요소에 등록된 이벤트 리스너가 이를 가로채거나 잡아낼 수 있다.
# 이렇게 이벤트를 걸러내어 해당 이벤트 리스너가 호출되지 않도록 하는 기법을 이벤트 취소 기법이라고 한다.

// 각 요소마다 캡쳐링 방식으로 click 이벤트 리스너를 등록함.
document.getElementById("divBox").addEventListener("click", clickDiv,  true);
document.getElementById("paraBox").addEventListener("click", clickPara,  true);
document.getElementById("spanBox").addEventListener("click", clickSpan,  true);


[이벤트 기본 동작의 취소]
HTML <a> 요소에 클릭(click) 이벤트가 발생하면 브라우저는 지정된 주소를 따라가 새로운 웹 페이즈를 열게된다.
- 이렇게 특정 이벤트는 미리 지정된 기본 동작을 가지고 있다.
- 하지만 preventDefault() 메소드나 returnValue 프로퍼티를 이용하면, 이러한 기본 동작의 실행을 취소가능

// 각 요소마다 버블링 방식으로 click 이벤트 리스너를 등록함.
document.getElementById("divBox").addEventListener("click", clickDiv);
document.getElementById("paraBox").addEventListener("click", clickPara);
document.getElementById("linkBox").addEventListener("click", clickLink);
function  clickDiv(event) {  document.getElementById("text").innerHTML  +=  "div 요소를 click 하셨네요!<br>";}
function  clickPara(event) {  document.getElementById("text").innerHTML  +=  "p 요소를 click 하셨네요!<br>";}
function  clickLink(event) {
    event.preventDefault(); // 링크의 기본 동작을 취소함.
    document.getElementById("text").innerHTML  +=  "링크의 기본 동작을 막았어요!<br>";
    document.getElementById("text").innerHTML  +=  "a 요소를 click 하셨네요!<br>";
}


[이벤트 전파의 취소]
이벤트의 전파도 취소할 수 있다.
# stopPropgation() 메소드나 cancelBubble 프로퍼티를 이용하면, 이러한 이벤트의 전파를 취소 가능
function  clickLink(event) {
    event.preventDefault(); // 링크의 기본 동작을 취소함.
    document.getElementById("text").innerHTML  +=  "링크의 기본 동작을 막았어요!<br>";
    event.stopPropagation(); // 이벤트의 전파를 취소함.
    document.getElementById("text").innerHTML  +=  "이벤트의 전파를 막았어요!<br>";
}
$(function() {
    $("#checked").change(function() {
        // checked 속성의 속성값을 반환
        $("#text").html("checked 속성의 속성값 : " + $(this).attr("checked") + 
            "<br> checked 프로퍼티 값: " + $(this).prop("checked"));  checked 프로퍼티 값을 반환
    }).change(); 값이 변할때마다 갱신
}); 

위 예제 실험해보기


이벤트 메소드


이벤트 메소드

on() 이외에도 자바스클비트 이벤트와 관련된 다양한 메소드를 제공한다.

  • 이러한 이벤트 메소드는 이벤트가 발생하는 요소에 따라 다음과 같이 구분
  1. 마우스 이벤트와 관련된 메소드
  2. 키보드 이벤트와 관련된 메소드
  3. 입력 양식(form) 이벤트와 관련된 메소드

마우스 이벤트와 관련된 메소드(.click(), .dblclick(), .hover())

  1. .click()
  2. .dblclick()
  3. .hover()

.dblclick()

  • 자바스크립트의 'dblclick' 이벤트와 이벤트 핸들러를 연결하거나
  • 해당 요소에 "dblclick"이벤트를 발생시킨다.
$(function() {    
    $("button").on("click", function() { // 모든 <button> 요소에 click 이벤트를 설정
        $("#clickText").css("color", "red");
        $("#dblclickText").css("color", "black");
    });

    $("button").on("dblclick", function() { // 모든 <button> 요소에 dblclick 이벤트를 설정
        $("#dblclickText").css("color", "red");
        $("#clickText").css("color", "black");
    });
});

.hover()

  • 자바스크립트의 "mouseenter"와 "mouseleave" 이벤트를 같이 이벤트 핸들러와 연결
  • $(function() {
      $("button").hover(function() { // 모든 <button>요소에 hover 이벤트를 설정함.
          $("#text").append("마우스가 버튼 위로 진입하거나 빠져나감<br>");
      });
    });

마우스 이벤트와 관련된 메소드




메소드 설명
.click() 자바스크립트의 "click" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "click" 이벤트를 발생시킴.
.dblclick() 자바스크립트의 "dblclick" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "dblclick" 이벤트를 발생시킴.
.hover() 자바스크립트의 "mouseenter"와 "mouseleave" 이벤트를 같이 인벤트 핸들러와 연결함.
.mousedown() 자바스크립트의 "mousedown" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "mousedown" 이벤트를 발생시킴.
.mouseenter() 해당 요소 위로 마우스가 진입할 때 발생하는 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 마우스 진입 이벤트를 발생시킴.
.mouseleave() 해당 요소에서 마우스가 빠져나갈 때 발생하는 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 마우스가 빠져나가는 이벤트를 발생시킴.
.mousemove() 자바스크립트의 "mousemove" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "mousemove" 이벤트를 발생시킴.
.mouseout() 자바스크립트의 "mouseout" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "mouseout" 이벤트를 발생시킴.
.mouseover() 자바스크립트의 "mouseover" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "mouseover" 이벤트를 발생시킴.
.mouseup() 자바스크립트의 "mouseup" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "mouseup" 이벤트를 발생시킴.



.keypress()

  • 자바스크립트의 "keypress" 이벤트와 이벤트 핸들러를 연결
$(function() {
    // 아이디가 "key"인 요소에 keypress 이벤트를 설정
    $("#key").on("keypress", function(event) {
        $("#str").html(event.type + " : " + event.which);
    });
});

// Shift, Esc, Delete 같은 화면에 출력되지 않는 키 (modifier and non-printing keys)들은 "keydown" 이벤트는 발생시키지만, "keypress" 이벤트는 발생시키지 않는다.

키보드 이벤트와 관련된 메소드




키보드 이벤트와 관련된 메소드

메소드 설명
.keydown() 자바스크립트의 "keydown" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "keydown" 이벤트를 발생시킴.
.keyup() 자바스크립트의 "keyup" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "keyup" 이벤트를 발생시킴.
.keypress() 자바스크립트의 "keypress" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "keypress" 이벤트를 발생시킴.



.focusin() , .focusout()

  • .focusin() 메소드는 자바스크립트의 "focusin" 이벤트와 이벤트 핸들러를 연결.
  • .focusout() 메소드는 자바스크립트의 "focusout" 이벤트와 이벤트 핸들러를 연결.
$(function() {
    // 아이디가 "focus"인 요소에 focusin 이벤트를 설정
    $("#focus").on("focusin", function(event) {
        $(this).css("backgroundColor", "yellow");
    });

    // 아이디가 "focus"인 요소에 focusout 이벤트를 설정
    $("#foucs").on("focusout", function(event) {
        $(this).css("backgroundColor", "white");
    });
});

// this 키워드는 현재 선택되어 있는 요소 그 자체를 가리킨다.

입력 양식 이벤트와 관련된 메소드




메소드 설명
.blur() 자바스크립트의 "blur" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "blur" 이벤트를 발생시킴.
.change() 자바스크립트의 "change" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "change" 이벤트를 발생시킴.
.select() 자바스크립트의 "select" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "select" 이벤트를 발생시킴.
.submit() 자바스크립트의 "submit" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "submit" 이벤트를 발생시킴.
.focus() 자바스크립트의 "focus" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "focus" 이벤트를 발생시킴.
.focusin() .focusin" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "focusin" 이벤트를 발생시킴.
.focusout() "focusout" 이벤트와 이벤트 핸들러를 연결하거나, 해당 요소에 "focusout" 이벤트를 발생시킴