Hoon222y

[JavaScript] 11장. 이벤트 본문

코딩/교육

[JavaScript] 11장. 이벤트

hoon222y 2019. 1. 10. 21:12

11.1 이벤트의 종류 

- 키보드를 이용해 버튼을 클릭하거나 마우스 클릭처럼 다른것에 영향을 미치는것


11.2 이벤트 관련 용어 정리 

1
window.onload = function () { };
cs

- 여기서 window 객체의 onload 속성에 함수 자료형을 할당하는 것을 '이벤트에 연결한다'고 한다.

- load를 이벤트 이름, 이벤트 타입 이라고 한다. 

- onload : 이벤트 속성

- 이벤트 속성에 할당한 함수이벤트 리스너, 이벤트 핸들러라고 한다. 


이벤트 모델 : 문서 객체에 이벤트를 연결하는 방법이며 DOM level 단계에 따라 2가지 2가지 방법으로 나뉘게 된다. 

DOM level 2 : 하나의이벤트에 대해서 여러개의 핸들러를 연결할 수 있다. 


11.3 고전 이벤트 모델

- 자바스크립트에서 문서 객체의 이벤트 속성으로 이벤트를 연결하는 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
    <script>
        window.onload = function () {
            var header = document.getElementById('header');
            // 이벤트를 연결합니다.
            header.onclick = function () {
                alert('클릭');
                header.onclick = null;
                //일회용 이벤트 처리 , 한번만 실행되고 앞으로는 안된다. 
            };
        };
    </script>
</head>
<body>
    <h1 id="header">Click</h1>
</body>
</html>
cs

 여기서 이벤트 리스너를 제거할 때는 문서 객체의 이벤트 속성에 null을 넣어주면 된다. (10번째 줄)


11.4 이벤트 발생 객체와 이벤트 객체

- 이벤트 리스너 안에서 this 키워드를 사용하면 이벤트가 발생한 객체를 찾을 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
    <script>
    function test(){
        alert(this); 
    }
    //test(); 이거처럼 독립적으로 하면 안됨
    window.onload = function(){
        document.querySelector('#header').onclick = test;
    }
    </script>
</head>
<body>
    <h1 id="header">Click</h1>
</body>
</html>
cs

 의 결과는 [object HTMLHeadingElement ] 이다. 여기서 주의할 점은 핸들러로 연결된 함수는 독립적으로 호출하면 안된다는 것이다. (8줄)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
    <script>
    function handler(){
        this.style.color = 'orange';
        this.style.backgroundColor = 'red';
    }
    window.onload = function () {
        document.getElementById('header').onclick = handler;
   };
    </script>
</head>
<body>
    <h1 id="header">Click</h1>
</body>
</html>
cs

는 click 을 클릭할 경우 배경이 red로 바뀐다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
    <script>
        window.onload = function () {
            document.getElementById('header').onclick = function (e) {
                var event = e || window.event;
                document.body.innerHTML = '';
                for (var key in event) {
                    document.body.innerHTML += '<p>' + key 
                                    + ': ' + event[key] + '</p>';
                }
            };
        };
    </script>
</head>
<body>
    <h1 id="header">Click</h1>
</body>
</html>
cs

 여기에서 7번째 줄을 보면 e가 존재하면 e를 event 변수에 넣고, e가 undefined 이면 window.event 속성을 event에 넣는 조건이다. 이는 익스플로어 8이하는 이벤트 객체를 window.event 속성으로 전달하지만, 다른 브라우저는 이벤트 리스너의 매개변수로 전달하기 때문이다. cross browsing


11.5 이벤트 강제 실행

- 메서드를 호출하는 것처럼 이벤트 속성을 호출하면 이벤트가 강제로 실행 

- 개발자와 브라우저가 실행하는 이벤트를 구별하는 방법은? 강제 실행은 이벤트 객체가 발생하지 않고, 이벤트 객체가 실행하는건 발생한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
<!DOCTYPE html>
<html>
<head>
    <script>
        window.onload = function () {
            // 문서 객체를 가져옵니다.
            var buttonA = document.getElementById('button-a');
            var buttonB = document.getElementById('button-b');
            var counterA = document.getElementById('counter-a');
            var counterB = document.getElementById('counter-b');
            // 이벤트를 연결합니다.
            buttonA.onclick = function () {
                counterA.innerHTML = Number(counterA.innerHTML) + 1;
            };
            buttonB.onclick = function () {
                counterB.innerHTML = Number(counterB.innerHTML) + 1;
                buttonA.onclick();
            };
        };
    </script>
</head>
<body>
    <button id="button-a"> ButtonA</button>
    <button id="button-b"> ButtonB</button>
    <h1>Button A - <span id="counter-a">0</span></h1>
    <h1>Button B - <span id="counter-b">0</span></h1>
</body>
</html>
cs

 18번째 줄을 보면 강제적으로 실행하는것을 볼 수 있다. 


11.6 인라인 이벤트 모델 

- 태그 래벨에서 태그의 이벤트 속성을 이용하여 이벤트를 처리하는 방식

1
2
3
<body>
    <h1 onclick="alert('클릭')">Click</h1>
</body>
cs

 해당과 같은 방식으로 사용 가능하다. 



11.7 디폴트 이벤트 제거

디폴트 이벤트 : 일부 HTML 태그가 이미 이벤트 리스너를 가지고 있는것. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<head>
    <script>
        window.onload = function () {            // 이벤트를 연결합니다.
            document.getElementById('my-form').onsubmit = function () {
                return false;
            }; //onsubmit 은 버튼을 클릭할 때 발생 하는것
        };
    </script>
</head>
<body>
    <form id="my-form">
        <label for="name">이름</label><br/>
        <input type="text" name="name" id="name" /><br/>
        <label for="pass">비밀번호</label><br/>
        <input type="password" name="pass" id="pass" /><br/>
        <label for="pass-check">비밀번호 확인</label><br/>
        <input type="password" id="pass-check" /><br/>
        <input type="submit" value="제출" />
    </form>
</body>
</html>
 cs
 에서 서브밋을 클릭하면 따로 이벤트를 넣지 않아도 서버로 전송을 한다. 이것이 바로 디폴트 이벤트이다. 이러한 이벹트 리스너를 제거하는 방법은 6번째 줄처럼 이벤트 return 값을 false로 설정한다. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
    <script>
        window.onload = function () {
            document.getElementById('my-form').onsubmit = function () {
                var pass = document.getElementById('pass').value;
                var passCheck = document.getElementById('pass-check').value;
                if (pass == passCheck) {
                    alert('성공');
                } else {
                    alert('다시 입력해주세요.');
                    return false;
                }
            };
        };
    </script>
</head>
cs

11.8 이벤트 전달

- 이벤트 버블링 : 자식노드에서 부모 노드 순으로 이벤트를 실행하는것을 의미 

- 부모는 어떤 자식에서 발생했는지 알 수 있어야지만 부모가 자식의 이벤트를 대신 처리해줄 수 있다. 존재하는 이유이다. 

 - 이벤트 전달 순서는 이벤트 버블링을 따름 

이벤트 버블링을 막기 위해서는 

익스플로어 : cancelBubble 속성를 true 로 한다.

그 외 : stopPropagation() 메서드 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
<head>
    <script>
        window.onload = function () {
            document.getElementById('header').onclick = function () {
                alert('header');
            };
            document.getElementById('paragraph').onclick = function (e) {
                alert('paragraph');
                // 이벤트 전달을 제거합니다.
                var event = e || window.event;
                event.cancelBubble = true;        //익스플로어
                if (event.stopPropagation) {    //그 외
                    event.stopPropagation();
                }
            };
        };
    </script>
</head>
<body>
    <h1 id="header">
        <p id="paragraph">Paragraph</p>
    </h1>
</body>
</html>
cs

 

이벤트 캡처링 : 부모 노드가 자식 노드 순으로 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script>
        function clickHandler(event){
            alert(event.target.innerHTML);
        }
        function init(){
            document.querySelector('#myList').onclick = clickHandler;
        }
        window.onload = init;
    </script>
    
</head>
<body>
    <ul id='myList'>
        <li>list 1</li>
        <li>list 2</li>
        <li>list 3</li>
    </ul>
</body>
</html>
cs

 여기에서 7 8 번째 줄에 매개변수로 event 가 들어가고, alert  매개변수에 this 가 아닌 event.target 이 들어간다. 


11.9 인터넷 익스플로러 이벤트 모델

- 두가지 



11.10 표준 이벤트 모델

이벤트 이름을 매개변수로 입력한다. onclick 이런식이 아니라 click 이렇게 

addEventListener(eventName, handler, useCapture)

removeEventListener(eventName, handler)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<head>
    <script>
    /* function handler1(){
        this.style.color = 'red';
    }
    function handler2(){
        this.style.backgroundColor = 'yellow';
    }
    function init(){
        var header = document.querySelector('#header');
        header.addEventListener('click',handler1);
        header.addEventListener('click',handler2);
    }         // 이런식으로 하는것이 맞음. 
    */
    function init(){
        var header = document.querySelector('#header');
        header.addEventListener('click',function(){
            this.style.color = 'blue';
        });
    }// 이렇게 하면 remove 를 못하기 때문에 익명함수 사용하지 말기
    
    window.addEventListener('load',init);
    </script>
</head>
<body>
    <h1 id="header">Click</h1>
</body>
</html>
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<head>
    <script>
        function submitHandler(event){
              var pass = document.querySelector('#pass').value;
              var passCheck = document.querySelector('#pass-check').value;
              if (pass == passCheck) {
                  alert('성공');
              } else {
                  alert('다시 입력해주세요.');
                  event.preventDefault();
              }
        };
        function init(){
            document.querySelector('#my-form').addEventListener('submit',submitHandler);
        }
        window.addEventListener('load',init);
    </script>
</head>
<body>
    <form id="my-form" action='passChange.jsp'>
        <label for="name">이름</label><br/>
        <input type="text" name="name" id="name" /><br/>
        <label for="pass">비밀번호</label><br/>
        <input type="password" name="pass" id="pass" /><br/>
        <label for="pass-check">비밀번호 확인</label><br/>
        <input type="password" id="pass-check" /><br/>
        <input type="submit" value="제출" />
    </form>
</body>
</html>
cs


'코딩 > 교육' 카테고리의 다른 글

[JSP & Servlet] 사전문제 & 2장  (1) 2019.01.15
[JavaScript] 2장. 기본 문법  (0) 2019.01.10
[JavaScript] 10장. 문서 객체 모델  (0) 2019.01.10
[JavaScript] 9장. 브라우저 객체 모델  (0) 2019.01.10
[JavaScript] 5장. 함수  (1) 2019.01.09
Comments