1. JavaScript 이벤트

          2. 이벤트 관련 용어

          3. 이벤트 전달

          4. 표준 이벤트 모델

          5. 기본 이벤트

 

 

1. JavaScript 이벤트

 

1) 이벤트(Event)

 

- 웹 페이지에서는 어떤 종류의 상호작용이 발생할 때 이벤트 발생

 

  • 사용자에 의한 상호작용 : 클릭하거나 특정 요소 위로 마우스를 가져가거나 특정한 키를 누르는 것 등
  • 브라우저에 의한 상호작용 : 웹 페이지의 로딩이 끝났다거나, 사용자가 페이지를 스크롤 하거나, 브라우저 창의 크기를 조절하는 것 등

- JavaScript를 통해 특정 객체에 이벤트가 일어나는 것을 감지할 수 있으며 그러한 이벤트들에 대응해서 어떤 일을 할      지 설정할 수 있다.

 

2) 이벤트 객체(event object)

 

- 이벤트가 발생했을 때 이벤트에 대한 정보와 기능을 담고 있는 객체

 

- 이벤트 객체는 이벤트가 발생할 때마다 자동으로 생성된다.

 

- 이렇게 생성된 이벤트 객체를 참조하고 싶다면 이벤트 핸들러의 매개변수로 받아 와서 활용할 수 있다.

 

 


2. 이벤트 관련 용어

 

⊙ 이벤트 이름(Event name), 이벤트 타입(Event type)

⊙ 이벤트 속성(Event attribute)

    - 객체의 이벤트 속성. 이벤트가 발생하면 이벤트 속성과 연결된 이벤트 핸들러 확인

⊙ 이벤트 핸들러(Event handler)

    - 이벤트가 발생했을 때 처리할 기능

 

<script>
    window.onload = function () {...};
        // onload → 이벤트 속성
        // function () {} → 이벤트 핸들러
    document.getElementById("header").onclick = function () {
        // onclick → 이벤트 속성
        // function () {} → 이벤트 핸들러(익명 함수)

        alert("Hello World!");
    };
</script>

 

예제) 이벤트 강제 발생

 

<script>
    var hello = document.getElementById("hello");
    var button = document.getElementsByTagName("button")[0];
    // → 객체의 배열 반환

    hello.onclick = function () {
        alert("Hello World!");
        button.onclick();
        // → 이벤트 속성에는 이벤트 핸들러가 연결되어 있기 때문에 
        //   이벤트 속성을 함수로써 실행시킨다는 것은 이벤트를 강제 발생시키는 것과 같다!
    };

    button.onclick = sayHello;

    function sayHello() {
        alert("Hello JavaScript!");
    }
</script>

 

연습문제 1)

: h1 요소를 클릭하면 그 요소가 1초에 걸쳐 점차 흐릿해지면서 화면에서 사라지는 프로그램과 button 요소를 클릭하면 h1의 배경 색상과 글자 색상을 바꾸는 프로그램을 작성하라.

 

<html>
    <head>
        <meta name="viewport" content="width=device-width">
        <meta charset="utf-8">
        <title>demo</title>
        <link rel="stylesheet" href="reset.css">
        <style>
            body {
                background-color: black;
            }

            #hello {
                width: 360px; height: 100px;
                line-height: 100px;
                margin: 50px auto 0;
                color: white;
                font-size: 35px;
                font-weight: 900;
                text-align: center;
                cursor: pointer;
            }

            p {
                width: 360px;
                margin: 25px auto;
            }

            button {
                height: 50px;
            }
        </style>
    </head>
    <body>
        <h1 id="hello">Hello World!</h1>
        <p>
            <button id="bg">bacground-color: yellowgreen</button>
            <button id="color">color: navy</button>
            <button id="reset">RESET</button>
        </p>

        <script>
            var hello = document.getElementById("hello");

            hello.onclick = function () {
                // 이벤트 핸들러: #hello 요소에 click 이벤트가 발생하면 실행할 기능

                // this 키워드: 메서드에서 객체를 나타내는 키워드
                //  → 따라서 이벤트 핸들러에서는 this 키워드가 "이벤트가 발생한 객체"를 나타낸다.
                //    여기에서는 #hello 요소를 표현하는 Element 객체가 된다.

                //#hello 요소가 1초에 걸쳐 흐릿하게 사라지도록 한다.
                this.style.transition = "1s ease-in";
                this.style.opacity = "0";
                this.style.visibility = "hidden";
            };

            document.getElementById("bg").onclick = bg_color;
            // 익명 함수가 아닌 선언적 함수를 식별자를 통해 대입하는 것도 가능하다.

            // document.getElementById("bg").onclick = sample_1();
            //  → sample_();는 함수를 호출하는 표현식이므로 이 문장은 틀린 문장이다.
            //    함수 자체를 대입해야 한다.

            document.getElementById("color").onclick = font_color;

            document.getElementById("reset").onclick = function () {
                // 이벤트 핸들러 : #reset 요소에 click 이벤트가 발생하면 실행할 기능

                // #hello 요소에 적용했던 스타일 속성 제거
                // hello.style.backgroundColor = "";
                // hello.style.color = "";
                hello.removeAttribute("style");
            };

            // 이벤트 핸들러 (선언적 함수 1) : #bg 요소에 click 이벤트가 발생하면 실행할 기능
            function bg_color() {
                // #hello 요소의 배경색 변경
                hello.style.backgroundColor = "yellowgreen";
            };

            // 이벤트 핸들러 (선언적 함수 2) : #color 요소에 click 이벤트가 발생하면 실행할 기능
            function font_color() {
                // #hello 요소의 글자색 변경
                hello.style.color = "navy";
            };
        </script>
    </body>
</html>

 

 

 

연습문제 2)

: button 요소를 클릭하면 h1 요소의 글자 색상을 red로 바꾸거나 본래 상태로 되돌리는 프로그램을 작성하라.

  이때 button의 요소의 내부 문자는 버튼의 기능에 따라 바뀌도록 한다.

 

<html>
    <head>
        <meta name="viewport" content="width=device-width">
        <meta charset="utf-8">
        <title>demo</title>
        <link rel="stylesheet" href="reset.css">
        <style>
            body {
                background-color: black;
                color: white;
            }

            #container {
                width: 350px;
                margin: 100px auto;
            }

            #hello {
                display: block;
                font-size: 50px;
                font-weight: 900;
                letter-spacing: -1px;
                text-align: center;
                line-height: 80px;
                background-color: #444;
                border-radius: 10px;
            }

            #color {
                width: 80px;
                line-height: 2;
                margin: 25px 135px;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <h1 id="hello">Hello World!</h1>
            <button id="color">COLOR</button>
        </div>

        <script>
            //---------------------------------------------------------------------------
            // 1. #color 요소를 클릭하면
            // 2-1. #color 요소의 내부 문자가 "COLOR"이면
            // 2-2 = (#hello 요소의 color 스타일 속성의 값이 없으면)
            // 3. #hello 요소의 글자 색상을 빨간색으로 바꾸고
            // 4. #color 요소의 내부 문자를 "RESET"으로 바꾼다.
            // 5. 그렇지 않으면
            // 6. #hello 요소의 글자 색상을 본래 색상으로 되돌리고
            // 7. #color 요소의 내부 문자를 "COLOR"으로 바꾼다

            //----------------------------------------------------------------------------
            // 1. #color 요소를 클릭하면
            //    → #color 요소에 click 이벤트 핸들러를 연결해서 구현
            document.getElementById("color").onclick = function () {
                // 이벤트 핸들러: #color 요소에 click 이벤트가 발생하면 실행할 기능

                // JavaScript에서 거짓을 의미하는 값
                // 1. number - 0
                // 2. string - ""
                // 3. boolean - false
                // 4. function - function () {}
                // 5. object - {}, []
                // 6. undefined

                // 2-1. #color 요소의 내부 문자가 "COLOR"이면
                // 2-2. #hello 요소의 color 스타일 속성의 값이 없으면
                // → if (!hello.style.color)
                if (this.innerHTML == "COLOR") {

                    // 3. #hello 요소의 글자 색상을 빨간색으로 바꾸고
                    hello.style.color = "red";

                    // 4. #color 요소의 내부 문자를 "RESET"으로 바꾼다.
                    this.innerHTML = "RESET";
                }
                // 5. 그렇지 않으면
                else {

                    // 6. #hello 요소의 글자 색상을 본래 색상으로 되돌리고
                    hello.style.color = "";

                    // 7. #color 요소의 내부 문자를 "COLOR"으로 바꾼다
                    this.innerHTML = "COLOR";
                }
            };        
        </script>
    </body>
</html>

 

 

 


3. 이벤트 전달

 

 

⊙ 이벤트 전달(event propagation)

 

- 하위 요소에서 발생한 이벤트는 상위 요소들에게 순차적으로 전달된다.

 

- 하위 요소에서 발생한 이벤트가 상위 요소에게 전달되지 않도록 막는 것을 "이벤트 전달을 제거한다"라고 표현한다.

 

- 이벤트 전달을 제거하는 방법 : 이벤트 객체의 stopPropagation 메서드를 호출

 

- 다른 요소에서 발생한 이벤트가 중첩된 다른 요소로 전달된다.

 

- JavaScript에서는 "이벤트 버블링" 방식에 따라 이벤트가 전달된다.

 

  • 이벤트 버블링 : 하위 요소에서 상위 요소로 이벤트가 전달되는 방식
  • 이벤트 캡처링 : 상위 요소에서 하위 요소로 이벤트가 전달되는 방식

 

 


4. 표준 이벤트 모델

 

⊙ 표준 이벤트 모델

 

    - W3C에서 지정한 DOM Level 2 이벤트 모델

    - 하나의 요소에 여러 이벤트 핸들러 추가 기능

    - 이벤트 캡처링 지원

    - IE8 이전 버전에서는 지원하지 않음 

 

     element.addEventListener( eventName, handler, useCapure );

     element.addEventListener( eventName, handler );

 

     eventName은 이벤트 속성이 아니라 이벤트 이름을 나타낸다.

     여기서 useCapure는 이벤트 캡처링 사용 여부(boolean)를 나타내고 생략 가능하다(생략 시 false).

 


5. 기본 이벤트(default event)

 

- 몇몇 HTML 요소들은 이벤트 핸들러를 연결하지 않아도 기본적으로 가지고 있는 기능들이 있다.

   이를 "기본 이벤트"라고 한다.

 

- 대표적으로 a 요소, input 요소, form 요소 등이 있다.

 

- 상황에 따라서는 이러한 기본 이벤트가 동작하지 않도록 제거해야 한다.

  이를 "기본 이벤트를 제거한다"라고 표현한다.

 

- 기본 이벤트를 제거하는 2가지 방법

 

  • 이벤트 객체의 preventDefault 메서드 호출 (주로 이 방법을 많이 쓴다.)
  • 이벤트 핸들러에서 false 반환

 

예제)

 

<html>
<head>
    <meta name="viewport" content="width=device-width">
    <meta charset="utf-8">
    <title>demo</title>
    <link rel="stylesheet" href="reset.css">
    <style>
         body {
            background-color: black;
        }

        #container {
            width: 200px;
            padding: 20px 40px;
            margin: 30px auto;
            background-color: #555;
            border-radius: 10px;
        }

        #google {
            display: block;
            text-align: center;
        }
    </style>
</head>
<body>

    <div id="container">
        <a href="http://www.google.com" id="google">Google</a>
    </div>

    <script>
        document.querySelector("#google").onclick = function (event) {
            // 이벤트 핸들러: #google 요소에 click 이벤트가 발생하면 실행할 기능

            // #google 요소는 a 요소이므로 click 이벤트가 발생하면 href 속성에 지정해 놓은
            // URL로 이동하는 것이 기본 이벤트이다.
            // 필요에 따라 이 기본 이벤트를 제거할 수 있고 제거하게 되면 url로 이동하지 않고
            // 인라인 스타일 속성에 지정되어 있는 스타일 속성만 적용된다.

            // 기본 이벤트를 제거하는 첫 번째 방법
            // → 이벤트 객체의 preventDefault 메서드 호출
            event.preventDefault();

            // 이벤트 전달 제거
            // → #google에 발생한 이벤트를 상위 요소들(#container, body, html)
            //   에게 전달되는 것을 막기 위해
            event.stopPropagation();

            this.style.color = "hotpink";

            // 기본 이벤트를 제거하는 두 번째 방법
            // return false;
            // 이 방법은 스타일 속성이 적용된 후에 작성되어야 한다.(순서 중요)

        };
        
        document.querySelector("#container").onclick = function () {
            // 이벤트 핸들러: #container 요소에 click 이벤트가 발생하면 실행할 기능

            this.style.backgroundColor = "navy";

            // 하위 요소(#google)에 발생한 이벤트는 상위 요소들(#container, body, html)
            // 에게 순차적으로 전달되므로 하위 요소에 이벤트 전달 제거를 해주지 않으면
            // #google을 클릭(onclick)하게 되면 상위 요소에 적용했던 스타일 속성까지 동시에 나타난다.
            // 그러므로 하위 요소(#google)에 "이벤트 전달을 제거"해야 한다 
        };
    </script>
</body>

 

 

 

몇 백줄이 지난 후, #google 요소의 이벤트 핸들러를 이미 작성했다는 사실을 잊어버려 다시 작성했다고 가정해보면

 

<script>
    document.querySelector("#google").onclick = function (event) {

        event.preventDefault();

        event.stopPropagation();

        this.style.color = "hotpink";
    };

    document.querySelector("#container").onclick = function () {

        this.style.backgroundColor = "navy";
    };

    //...
    //...

    document.querySelector("#google").onclick = function (event) {
        // 이벤트 핸들러(#google 요소에 click 이벤트가 발생하면 실행할 기능)를 통해
        // 스타일 속성을 "추가"할 목적으로 작성

        event.preventDefault();

        this.innerHTML = "Go Google!";
    };
</script>

 

 

 

위와 같이 이벤트 핸들러를 통해 스타일 속성을 추가할 목적으로 작성했지만 추가되지 않고

기존에 적용되었던 스타일 속성을 덮어쓰게 된다.

변수에 또 다른 값을 대입하면 초기화되는 것과 같이 이와 같은 경우에도

여기서 작성된 스타일 속성이 앞에서 작성된 핸들러를 통해 실행할 스타일 속성을 덮어쓰게 된다.

이러한 문제점을 addEventListener를 통해 해결해야 한다.

 

<script>
    document.querySelector("#google").onclick = function (event) {

        event.preventDefault();

        event.stopPropagation();

        this.style.color = "hotpink";
    };

    document.querySelector("#container").onclick = function () {

        this.style.backgroundColor = "navy";
    };

    //...
    //...

    document.querySelector("#google").addEventListener("click", function () {

        // 기본 이벤트 제거
        event.preventDefault();

        // 스타일 속성 설정
        this.innerHTML = "Go Google!";
    });

    // 이벤트 핸들러와 객체를 다룰 때는 되도록 addEventListener으로 작성하는 것이 좋다.
	};
</script>