본문 바로가기
03. 웹 표준 기술/JavaScript

[자바스크립트] 11. event + 정규표현식 맛보기

by moca7 2024. 8. 14.

 

 

ㅁ < 이벤트 Event >

- DOM 객체에서 발생되는 시그널

- 시스템에서 일어나는 사건(Action) 또는 발생(Occurence)를 의미한다.

 

- 주요 이벤트 발생 방식

(1) 사용자의 액션에 의해서 생성 (클릭, 키보드 입력, 마우스 움직임 등)

(2) API의 이벤트 생성

 

 

 

 

< 이벤트 핸들러 Event Handler >

- 이벤트 발생시 동작시킬 함수

 

- 이벤트 핸들러(함수) 동작시 이벤트 핸들러의 매개변수로

발생된 이벤트에 대한 각종 정보들이 담겨있는 Event 객체가 인자로 자동 전달된다.

- 이벤트 핸들러(함수)를 작성할 때 매개변수를 두면 이벤트 객체가 전달된다.

매개변수명은 관례상 "event" 또는 "evt"로 한다.

 

 

 

 

이벤트 모델 Event Model

- 이벤트가 발생했을 때 이벤트 핸들러를 할당하는 방법을 이벤트 모델이라고 한다.

 

- 종류

(1) 고전이벤트 모델

(2) 인라인 이벤트 모델

(3) 표준 이벤트 모델

 

 

 

 

 

 

ㅁ 고전 이벤트 모델

 

- DOM 객체의 이벤트 핸들러 속성(property)을 활용하는 방법.

 

- 이벤트 종류 앞에 "on"키워드를 붙이면 이벤트 핸들러 속성이다.

ex) onclick, onkeydown, onsubmit

 

- 하나의 이벤트 핸들러 속성에 하나의 이벤트핸들러만 할당 가능하다.

- 이벤트 핸들러 속성에 null 대입시 이벤트 핸들러 제거 가능하다.

 

 

 

 

(1) 익명함수

 

DOM 객체.onclick = function() {          //    이벤트 핸들러

 

}

 

 

(2) 화살표 함수

 

DOM 객체.onclick = () => {          //    이벤트 핸들러

 

}

 

 

 

(3) 기명함수

 

function eventHandler() {         //    이벤트 핸들러

 

}

DOM 객체.onclick = eventHandler;     //     미리 선언하고 대입 (괄호 없어야 함)

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>이벤트 모델(Event Model)</h2>

   
    <h3>고전 이벤트 모델</h3>
    <button id="btn1">고전이벤트모델1</button> <!-- 버튼 내에 onclick 속성을 쓰지 않음. -->
    <button id="btn2">고전이벤트모델2</button>
    <button id="btn3">고전이벤트모델3</button>
 



    <script>

        (1) 익명함수
        const btn1El = document.getElementById("btn1");   //   전역함수

   
        btn1El.onclick = function() {
            console.log('btn1 클릭');
        }
        btn1El.onclick = function() {
            alert("btn1 클릭");
        }
        // alert에도, console에도 띄우고 싶지만. alert 알림창으로는 뜨는데 콘솔에는 안 뜬다.
        // 하나의 이벤트 핸들러 속성에 하나의 이벤트 핸들러만 할당 가능하다.
 
 


        (2) 화살표 함수
        const btn2El = document.getElementById("btn2");   

        btn2El.onclick = () => {
            console.log('btn2 클릭, btn1클릭 이벤트핸들러 제거');
            btn1El.onclick = null;   //   이러면 첫번째 버튼 눌러도 아무 반응 없음.
        }
 
 



        (3) 기명함수
        const btn3El = document.getElementById("btn3");
        btn3El.onclick = fnAction;   //   이미 존재하는 함수를 대입할 때는 괄호열고 닫으면 안 됨. 함수명만 써야 함. 실행되버림.

        function fnAction() {
            console.log("fnAction함수 실행");
        }

       

    </script>


</body>
</html>

 

 

 

- 이미 존재하는 함수를 대입할 때는 괄호를 열고 닫으면 안 된다. 함수명만 써야 한다.

 

 

 

 

 

인라인 이벤트 모델

- HTML 요소 내에 직접 이벤트 핸들러 속성을 작성하고 실행할 함수를 호출

- 이벤트 핸들러 작성시 주로 기명함수를 사용

- 인라인 이벤트 모델 방식은 <button onclick="firstHandler(); secondHandler();">Click me</button>

이렇게 하나의 onclick 속성에 여러 핸들러를 추가할 수 있다.

 

 

ㅇ 인라인 이벤트 모델 예시

 

<button onclick="inline();">버튼</button>

 

function inline() {   }

 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>이벤트 모델(Event Model)</h2>


    <h3>인라인 이벤트 모델</h3>
    <button onclick="fnClickedFunc();">인라인이벤트모델</button>



    <script>

        function fnClickedFunc() {
 
            console.log("인라인 이벤트 모델 방식");
           
        }

    </script>


</body>
</html>

 

 

 

 

 

 

 

ㅁ 표준 이벤트 모델

- 이게 w3c 재단에서 권장사항이다. 그런데 인라인 방식을 많이 쓴다.

그래도 이 방식을 쓰는게 좋음. 근데 간혹가다 지원하지 않는 브라우저가 있다. IE 9 이하에서는 지원 안 함.

- 여기서도 button에 onclick속성 안 쓴다. button에 onclick 속성 쓰는건 무조건 인라인 방식이다.

 

 

- W3C에서 공식적으로 지정한 이벤트 모델

- addEventListener() 메소드를 호출하는 방식

- 감지할 이벤트와 해당 이벤트 발생시 실행시킬 이벤트 핸들러 작성

- 하나의 이벤트에 여러개의 이벤트 핸들러 할당 가능

( 고전 이벤트 모델은 하나의 이벤트에 여러 개의 이벤트 핸들러를 할당할 수 없다. )

( 인라인 이벤트 모델은 할당이라고 볼 수 없다. 그냥 속성값으로 실행시키고자 하는 소스코드를 작성하는 방식이다. ) 

 

 

 

 

(1) 익명함수 

DOM 객체.addEventListener( "click", function( ) )

 

첫번째 매개변수 : 감지할 이벤트명(on이 붙지 않은 이벤트 종류)

두번째 매개변수 : 그때 실행시킬 이벤트 핸들러

 

 

 

(2) 화살표 함수

DOM 객체.addEventListener( "click", ( ) => {

 

} )

 

 

 

(3) 기명함수

function eventHandler( ) {  }

DOM 객체.addEventListener( "click", eventHandler );

 

// 미리 선언한 함수를 전달할 때 괄호 열고닫지 않음. 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>이벤트 모델(Event Model)</h2>


    <h3>표준 이벤트 모델</h3>
    <button id="btn1">표준이벤트모델1</button>
    <button id="btn2">표준이벤트모델2</button>
    <button id="btn3">표준이벤트모델3</button>



    <script>

        // 익명함수
        const btn1El = document.getElementById("btn1"); // 전역변수

        btn1El.addEventListener("click", function() {
            console.log("btn1 클릭");
        } )

        // 동일한 이벤트에 두 개의 이벤트 핸들러 연결
        // 고전 이벤트 모델은 마지막에 연결한 이벤트 핸들러만 작동되었었다.
        btn1El.addEventListener("click", function() {
            alert("btn1 클릭");
        } )




        // 화살표 함수
        const btn2El = document.getElementById("btn2"); // 전역변수

       
        // 마우스가 버튼에 올라가고 내려갈 때 사실 이벤트가 발생한다.
        btn2El.addEventListener("mouseenter", ( ) => {
            console.log("btn5 마우스 올라감");
        } )
        btn2El.addEventListener("mouseout", ( ) => {
            console.log("btn5 마우스 빠져나감");
        } )        




        // 기명함수
        document.getElementById("btn3").addEventListener("dblclick", fnAction);   //   더블클릭. 괄호 없어야 함.

        function fnAction() {
            console.log("fnAction함수 실행");
        }

    </script>


</body>
</html>

 

 

 

 

 

 

 

=================================================================================

 

 

 

ㅁ 알게 모르게 브라우저를 이용하면서 이벤트가 많이 발생한다. 

키보드로 뭘 입력하거나, 뭘 누르거나, 마우스를 올리거나 내리거나. 

알게 모르게 이벤트 객체들이 항상 만들어지고 있다.

어떤 요소에 어떤 이벤트가 발생했는지에 대한 정보를 이벤트 객체가 가지고 있다.

 

 

 

ㅁ 이벤트 객체 

- 이벤트가 발생하는 순간 브라우저에 의해 만들어진다.

- 현재 발생한 이벤트에 대한 상세정보를 가지고 있다. (이벤트 종류, 이벤트 대상, 이벤트 위치 등)

 

- 이벤트 핸들러의 매개변수로 이벤트 객체가 전달된다.

(이벤트 핸들러를 작성할 때 매개변수를 두면 이벤트 객체가 전달됨)

(이 때 매개변수명은 관례상 "event" 또는 "evt")

 

 

 

 

ㅇ 주요 속성

 

(1) type

- 발생된 이벤트의 종류

- 마우스 이벤트 : click, dblclick, mouseover, mouseout, mousemove, mouseup, mousedown, ... 

- 폼 요소 이벤트 : submit

- 키보드 이벤트 : keydown, keypress, keyup

...

 

(2) target

- 이벤트가 발생된 요소객체

 

 

 

 

 

 

 

ㅁ 현재 이벤트가 발생된 요소에 접근하기

- 화살표 함수, 기명함수(선언적 함수)에서는 this 사용 불가(해당 요소 객체가 아닌 window 객체를 가리켜서)

- 기명함수에서는 window.event.target 이용해서 이벤트 발생된 요소객체 활용.

- 화살표함수에서는  window.event.target, 매개변수로 evt로 이벤트 객체 전달받아 evt.target으로 활용.

- 익명함수에서는 window.event.target, evt.target, this 다 활용 가능.

- window.event.target은 다 가능.

 

 

 

(1) 고전 이벤트 방식 - 익명함수

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="origin">고전이벤트방식</button>

 
    <script>

      // 고전이벤트방식(익명함수)
      document.getElementById("origin").onmouseenter = function(evt) {
        console.log(window.event);         // window.event : Event객체
        console.log(evt);                          // evt                  : Event객체
 
        console.log(window.event.target);     // window.event.target : 현재 이벤트가 발생된 요소객체 (o)
        console.log(evt.target);                      // evt.target                  : 현재 이벤트가 발생된 요소객체 (o)
        console.log(this);                               // this                            : 현재 이벤트가 발생된 요소객체 (o)
 
      }

 
    </script>


</body>
</html>
 

 

 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="origin">고전이벤트방식</button>
 

 
    <script>

      // 고전이벤트방식(익명함수)
      document.getElementById("origin").onmouseenter = function(evt) {
 
        console.log(window.event);    // window.event : Event객체
        console.log(evt);                     // evt                  : Event객체
 
        console.log(window.event.target);    // window.event.target : 현재 이벤트가 발생된 요소객체 (o)
        console.log(evt.target);                    // evt.target                   : 현재 이벤트가 발생된 요소객체 (o)
        console.log(this);                              // this                           : 현재 이벤트가 발생된 요소객체 (o)
 
 
        // 이벤트가 발생된 요소객체 조작
        window.event.target.innerHTML = '마우스올라감';
        evt.target.style.fontSize = "32px";
        this.style.backgroundColor = "red";
 
      }

 
    </script>


</body>
</html>
 

 

 

- this는 현재 이벤트가 발생한 요소 객체다.

 

 

 

 

(2) 고전 이벤트 방식 - 화살표 함수 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="origin">고전이벤트방식</button>
 

 
    <script>
     
      // 고전이벤트방식(화살표함수)
      document.getElementById("origin").onclick = evt => {
 
        console.log(window.event.target);    // window.event.target  : 현재 이벤트가 발생된 요소객체 (o)
        console.log(evt.target);                     // evt.target                  : 현재 이벤트가 발생된 요소객체  (o)
        //console.log(this);                            // this                            : window 객체 (즉, 사용불가)        (x)
 
     
        window.event.target.innerHTML = "클릭됨";
        evt.target.style.border = "2px solid blue";
 
      }

 
    </script>


</body>
</html>
 

 

 

 

 

 

(3) 인라인 이벤트 방식 - 기명함수

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="inline" onclick="fnInline();">인라인이벤트방식</button>

 
    <script>

      // 인라인이벤트방식(기명함수)
      function fnInline(evt) {
 
        console.log(window.event.target);         // window.event.target : 현재 이벤트가 발생된 요소객체 (o)
        //console.log(evt.target);                        // evt.target                  : evt는 undefined (즉, 사용불가)  (x)
        //console.log(this);                                 // this                            : window 객체 (즉, 사용불가)       (x)
 
 
        const eventEl = window.event.target;
        eventEl.innerHTML = "클릭됨";
        eventEl.style.color = "green";
 
      }


 
    </script>


</body>
</html>
 

 

 

 

 

 

 

 

(4) 표준 이벤트 방식 - 익명함수

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="standard">표준이벤트방식</button>
 
 
    <script>

      // 표준이벤트방식(익명함수)
      document.getElementById("standard").addEventListener("mouseenter", function(evt) {
 
        console.log(window.event.target);   // window.event.target : 현재 이벤트가 발생된 요소객체 (o)
        console.log(evt.target);                    // evt.target                  : 현재 이벤트가 발생된 요소객체 (o)
        console.log(this);                             // this                            : 현재 이벤트가 발생된 요소객체 (o)
 
      })

 
    </script>


</body>
</html>
 

 

 

 

(5) 표준 이벤트 방식 - 화살표 함수

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
    <h2>현재 이벤트가 발생된 요소에 접근하기</h2>

    <button id="standard">표준이벤트방식</button>
 
 
    <script>

      // 표준이벤트방식(화살표함수)
      document.getElementById("standard").addEventListener("click", evt => {

        console.log(window.event.target);    // window.event.target : 현재 이벤트가 발생된 요소객체  (o)
        console.log(evt.target);                     // evt.target                  : 현재 이벤트가 발생된 요소객체  (o)
        //console.log(this);                            // this                            : window 객체 (즉, 사용불가)        (x)
       
      });

 
    </script>



</body>
</html>
 

 

 

 

 

 

 

ㅁ 예제 - 버튼 클릭시 해당 버튼의 배경색을 해당 버튼의 innerHTML 값으로 변경

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
  <h2>적용예시</h2>

  <!-- 세버튼 클릭시 해당 버튼의 배경색을 해당 버튼의 innerHTML값으로 변경 -->
  <button id="red" onclick="fnChangeRed();">red</button>
  <button id="green" onclick="fnChangeGreen();">green</button>
  <button id="blue" onclick="fnChangeBlue();">blue</button>
 

  <script>
   
    function fnChangeRed(){
      document.getElementById("red").style.backgroundColor = "red";
    }

    function fnChangeGreen(){
      document.getElementById("green").style.backgroundColor = "green";
    }

    
function fnChangeBlue(){
      document.getElementById("blue").style.backgroundColor = "blue";
    }

  </script>


</body>
</html>
 

 

- 이렇게 함수를 다 따로 만들고 각 버튼 클릭시 이 함수들을 호출시킬 수도 있지만, 하나의 함수로 통일할 수도 있다.

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
  <h2>적용예시</h2>

  <!-- 세버튼 클릭시 해당 버튼의 배경색을 해당 버튼의 innerHTML값으로 변경 -->
  <button id="red" onclick="fnChangeBackground();">red</button>
  <button id="green" onclick="fnChangeBackground();">green</button>
  <button id="blue" onclick="fnChangeBackground();">blue</button>
  <button onclick="fnChangeBackground()">pink</button>

  <script>

    function fnChangeBackground() {
 
      const clickedBtn = window.event.target;
      clickedBtn.style.backgroundColor = clickedBtn.innerHTML;
 
    }

  </script>


</body>
</html>
 

 

- fnChangeBackground 함수 하나를 정의해서 각 버튼 클릭시 동일하게 이 함수를 호출시킬 수 있다.

- 클릭 이벤트가 발생한 요소 객체를 window.event.target으로 가져와서 변수에 기록.

- 각 기능의 함수를 따로 정의해서 따로 호출할 필요 없이, 한번에 정의해서 모든 버튼에 동일한 함수를 실행시켰다.

그때 어떤 버튼 요소가 클릭될 지는 모르겠지만 클릭된 버튼 요소가 필요하다면 그 함수 내에서 window.event.target을 이용해서 가져올 수 있다.

 

 

- innerHTML로 그냥 가져와서 따옴표 안붙이고 대입했음.

 

innerHTML은 HTML 요소의 콘텐츠를 문자열로 반환합니다.

예를 들어, <button id="red">red</button>에서 button 요소의 innerHTML은 "red"입니다.

이 값은 이미 문자열이기 때문에, 자바스크립트에서는 추가적인 따옴표가 필요 없습니다.

 

 

 

 

==============================================================================

 

 

 

 

ㅁ 키보드 관련 이벤트

- 사용자가 텍스트상자를 클릭해서 키보드로 무언가를 입력할 때도 이벤트가 발생한다. 

- 키보드 관련 이벤트는 텍스트 상자에 사용자가 무언가를 입력할 때 마다 사용자가 입력한 값을 가져와서 검수해야 한다든가 할 때 사용한다.

사용자가 유효한 형식으로 잘 입력하고 있는지 실시간으로 입력된 값을 가져와야하는 때가 있다.

 

- 종류

 

(1) keydown : 키가 눌려질 때 발생되는 이벤트 (모든 키 감지)

(2) keypress : 키가 눌려질 때 발생되는 이벤트 (펑션키, 기능키, 한글 제외한 키 감지 - 영문, 숫자키 정도만 감지)

(3) keyup      : 키가 떼어질 때 발생되는 이벤트 (모든 키 감지)

 

 

 

 

ㅁ (1) keydown, (2) keypress

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>키보드 관련 이벤트</h2>
    <textarea id="content" cols="30" rows="10" style="resize:none" placeholder="내용을 입력해주세요"></textarea>


    <script>

        document.getElementById("content").onkeydown = function(evt) {
 
            console.log('이벤트발생');

        }

    </script>

</body>
</html>
 

 

 

 

- 텍스트상자를 input type=text로 한줄짜리말고, textarea로 여러줄 입력할 수 있는 텍스트 상자를 둬 본다. 

- 브라우저에서 textarea 내부를 클릭하면 focus 상태가 된다.

 

- alt, shift, 펑션키(f10 등)가 눌려질때마다 keydown 이벤트가 발생하여 콘솔창에 '이벤트발생'이 출력된다.

- keydown을 keypress로 바꾸면 영문, 숫자키는 잘 작동되지만 한글키, 기능키, 펑션키 등에는 작동하지 않는다.

- 꾹 누르면 keydown 이벤트가 계속 발생한다. keypress도 누르는 동안 이벤트가 계속 발생한다.

 

 

 

 

 

 

ㅁ (3) keyup

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2>키보드 관련 이벤트</h2>
    <textarea id="content" cols="30" rows="10" style="resize:none" placeholder="내용을 입력해주세요"></textarea>


    <script>

        document.getElementById("content").onkeyup = function(evt) {
            console.log('이벤트발생');
            console.log(evt);

        }

    </script>

</body>
</html>
 

 

 

 

- keyup은 계속 키보드를 누르고 있어도 계속 발생 안 함. 키보드에서 손을 떼면 그 때 한 번만 이벤트가 발생한다.

- 저 함수가 실행될 때 마다 현재 발생하는 이벤트 정보가 담겨있는 이벤트 객체가 전달이 되어서 매개변수 evt에 담겨있다.

 

 

 

 

- keyboardEvent 라는 객체가 보이고 펼쳐보면 여러 속성을 가지고 있다.

어떤 타입인지(type), 어느 영역의 이벤트인지 그 요소객체 가리키고 있다(target).

- key 속성은 현재 눌려진 키 값.

keyCode는 사용자가 키보드에서 누르는 키에 대한 코드.

(키코드는 한글은 제대로 나오지 않고 영문 입력해야 한다)

 

 

- 텍스트 상자에 입력을 다 끝내고 엔터키를 치는 순간 무언가 수행되게끔 하고 싶을 때,

현재 눌려진 키가 엔터일 경우라는 조건을 종종 쓴다.

그럴때 key, keyCode를 가져와서 비교를 한다.

- Enter 키코드는 13.

 

 
        document.getElementById("content").onkeyup = function(evt) {
 
            console.log('key속성: ', evt.key);
            console.log('keyCode속성: ', evt.keyCode);
 
        }
 

 

- 현재 눌려진 키 하나에 대한 정보를 알 수 있다.

- 키를 누를 때 마다 어떤 키가 눌렸는지, 그 키코드 값이 뭔지 Event 객체로부터 알아낼 수 있다.

 

 

 

 

 

- 만약 텍스트 상자에 실시간으로 사용자가 입력한 값 전체를 알고 싶다면 text상자의 value값 가져오면 된다.

 
        document.getElementById("content").onkeyup = function(evt) {
 
            console.log('key속성: ', evt.key);
            console.log('keyCode속성: ', evt.keyCode);
            console.log('입력란에 작성된값: ', evt.target.value);
 
        }
 

 

 

한글 입력하면 key 속성이 Process로 나옴.

 

 

 


- 글자 수도 실시간으로 알 수 있다.

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>


    <h2>키보드 관련 이벤트</h2>
    <span id="text_length">0</span>/200<br>
    <textarea id="content" cols="30" rows="10" style="resize:none" placeholder="내용 입력"></textarea>


    <script>


        document.getElementById("content").onkeyup = function(evt) {
 
            console.log('key속성: ', evt.key);
            console.log('keyCode속성: ', evt.keyCode);
            console.log('입력란에 작성된값: ', evt.target.value);
 

            document.getElementById("text_length").innerHTML = evt.target.value.length;
 
        }



    </script>


</body>
</html>
 

 

 

 

 

 

 

 

==========================================================================

 

 

 

 

< 이벤트 전파(이벤트 버블링) >

- 복잡하게 요소 작업을 하다보면 요소 안에 요소가 있을 수 있다. (중첩작성)

이때 이 요소들에 이벤트가 여러개 걸려있을 경우 이벤트 버블링 현상이 발생할 수 있다.

 

- 요소들이 중첩되어있을 경우 내부 요소에 이벤트 핸들러가 동작된 후

상위 요소들의 이벤트 핸들러도 같이 동작되는 현상.

- 최상위 요소에 도달할 때까지 반복적으로 진행됨.

 

- Event 객체의 stopPropagation() 메소드를 통해 이벤트 전파를 중지시킬 수 있다.

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>


    <h2>이벤트 전파</h2>

    <style>
        .bubbling { margin: 10px; border: 1px solid gray; }
        #child { width: 160px; }
        #parent { width: 200px; }
        #ancestor { width: 240px; }
    </style>


    <div id="ancestor" class="bubbling">조상div
        <div id="parent" class="bubbling">부모div
            <div id="child" class="bubbling">자식div</div>
        </div>
    </div>


 
    <script>



    </script>
</body>
</html>
 

 

- 기본세팅.

- 요소가 중첩되어 있다.

이때 자식 요소에도 클릭 이벤트가 있고, 부모 요소에도 클릭 이벤트가 있고, 조상 요소에도 클릭 이벤트가 있으면,

기본적으로 안쪽의 요소를 클릭하는 순간 그 상위 요소들의 이벤트도 같이 작동된다.

이게 이벤트 버블링 효과이다. 

 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   

    <h2>이벤트 전파</h2>

    <style>
        .bubbling { margin: 10px; border: 1px solid gray; }
        #child { width: 160px; }
        #parent { width: 200px; }
        #ancestor { width: 240px; }
    </style>


    <div id="ancestor" class="bubbling">조상div
        <div id="parent" class="bubbling">부모div
            <div id="child" class="bubbling">자식div</div>
        </div>
    </div>


 
    <script>

        const ancestor = document.getElementById("ancestor");
        const parent = document.getElementById("parent");
        const child = document.getElementById("child");


        // 조상, 부모, 자식 div에 클릭 이벤트 부여 (표준 이벤트 방식으로)
        ancestor.addEventListener("click", evt => {

            console.log('조상div 이벤트핸들러 작동');

        });

        parent.addEventListener("click", evt => {

            console.log('부모div 이벤트핸들러 작동');

        });

        child.addEventListener("click", evt => {

            console.log('자식div 이벤트핸들러 작동');


        });
 

    </script>
</body>
</html>
 

 

 

 

 

 

- 브라우저에서 자식 div 영역을 클릭하면 자식 div의 이벤트핸들러뿐만 아니라 부모, 조상 div의 이벤트핸들러도 동작한다.

안쪽 요소를 클릭할 때 상위 요소(부모, 조상 div)들도 같이 클릭 되기 때문이다..

- 부모 div 영역을 클릭하면 부모 div 이벤트핸들러 뿐만 아니라, 조상 div 이벤트 핸들러도 작동한다.

- 조상 div 영역을 클릭하면 조상 div 이벤트핸들러만 작동한다.

 

 

 

 

ㅁ 이벤트 전파(이벤트 버블링) 방지

 

 
        ancestor.addEventListener( "click", evt => { console.log("조상div 이벤트핸들러 작동"); }  );
 
        parent.addEventListener( "click", evt => {
 
            console.log("부모div 이벤트핸들러 작동");
            evt.stopPropagation();        // 이벤트 전파 막기
 
        }  );
 
        child.addEventListener( "click", evt => {
 
            console.log("자식div 이벤트핸들러 작동");
            evt.stopPropagation();       // 이벤트 전파 막기
 
        }  );
 

 

 

- 이벤트 핸들러 호출시 매개변수로 전달받은 Event 객체의 stopPropagation() 메소드를 사용해 이벤트 전파를 막을 수 있다.

- 이러면 상위 요소의 이벤트 핸들러는 실행 안 됨.

 

 

- 모든 이벤트 핸들러마다 Event객체.stopPropagation();를 쓰라는 게 아니라

요소들이 중첩되어 있을 경우 이벤트 버블링 현상이 발생하면 사용해서 제어해라.

- Event객체가 워낙 자주 사용되서 보통 이벤트 핸들러를 쓸 때는 Event 객체를 받아줄 매개변수를 당장 사용하지 않더라도 써두는 것이 좋다. 언제 쓰게 될 지 모름.

이벤트 핸들러를 쓸 때는 Event 객체를 받아줄 매개변수를 항상 써두는 습관을 들이는 것이 좋다.

 

 

 

 

 

==============================================================================

 

 

 

 

ㅁ 디폴트 이벤트

- 기본적으로 이벤트를 가지고 있는 요소들이 몇 있다.

내가 이벤트를 부여하지 않아도 자동으로 이벤트 발생시 작동되는 내용이 정의되어 있는 요소들이 있다.

 

- 몇몇 DOM 객체는 특정 이벤트를 기본적으로 이미 가지고 있다.

- 주요 디폴트 이벤트

(1) <a> 태그는 click시 href속성으로 이동함

(2) <form> 내의 submit 버튼은 click시 서버측으로 데이터를 전송한다.

 

- 디폴트 이벤트 막기

Event 객체의 preventDefault() 메소드 호출

 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   

    <h2>디폴트 이벤트</h2>

    <a id="naver-link" href="http://www.naver.com" target="_blank">네이버로 이동</a>
    <br><br>

 
    <form action="/server/test.do" method="get">
        아이디 : <input type="text" name="userId" id="userId"> <br>
        비밀번호 : <input type="password" name="userPwd" id="userPwd"> <br>
        비밀번호 확인 : <input type="password" id="checkPwd"> <br><br>
        <input type="submit" id="submit">
    </form>

 
    <script>

    </script>
   
</body>
</html>
 

 

 

- a 태그.

클릭 이벤트를 넣지 않아도 기본적으로 클릭시 href에 작성된 url 주소로 페이지가 전환되는 기능을 가지고 있다.

- submit 태그.

form 안에 있어야 작동함.

form 안에 무언가를 제출하는 <input type="submit">으로 submit 버튼을 둘 수 있다.

얘도 디폴트 이벤트를 가지고 있다. 

 

- action에는 요청할 서버의 주소를 기술한다. 우선은 test.do로 대충 표기한다. 

- name 속성으로 key 값을 부여해야 값이 정상적으로 넘어간다.

- 비밀번호 확인은 서버로 값을 넘길 필요는 없다. 

클라이언트측에서 일치하는지 비교하는지가 목적이다. 그래서 name은 안 줘도 된다.

- form 내의 submit 버튼은 기본적으로 클릭 이벤트를 가지고 있다.

사용자가 입력한 값들을 서버측으로 전송하면서 요청을 보내는 기능을 가지고 있다. 디폴트 이벤트다.

 

 

 

 

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>
<body>
 

    <h2>디폴트 이벤트</h2>

    <a id="naver-link" href="http://www.naver.com" target="_blank">네이버로 이동</a>
    <br><br>

    <form action="/server/test.do" method="get">
        아이디 : <input type="text" name="userId" id="userId"> <br>
        비밀번호 : <input type="password" name="userPwd" id="userPwd"> <br>
        비밀번호 확인 : <input type="password" id="checkPwd"> <br><br>
        <input type="submit" id="submit">   <!-- 선택가능하게끔 id를 준다. id를 주는 이유는 선택하기 위함이다. -->
    </form>



    <script>
       
        document.getElementById("naver-link").addEventListener("click", function(evt) {

                evt.preventDefault();
 
        })


    </script>


</body>
</html>
 

 

 

- a 태그는 기본적으로 클릭 이벤트를 가지고 있지만 내가 다시 클릭이벤트를 작성할 수 있다.

클릭이벤트 발생시 실행할 함수 작성 가능.

이벤트 객체를 전달받기 위해 매개변수를 써둔다.

 

- 이벤트 객체.preventDefault();를 작성해 놓으면 a 요소를 클릭해도 아무일도 일어나지 않는다.

 

 

 

 

 
        document.getElementById("naver-link").addEventListener("click", function(evt) {
            if( !confirm("페이지 이동하시겠습니까?")) {
                evt.preventDefault();
            }    
        })
 

 

- 이렇게 작성하면 사용자에게 의사를 물어서 페이지 이동을 할지 말지 결정하게할 수 있다. 

- 기본이벤트보다 내가 부여한 이벤트가 먼저 실행된다. 

 

 
    confirm("페이지 이동하시겠습니까?") || evt.preventDefault();   //   shortCircuit 사용
 

 

- shortCircuit으로 ||를 쓰고 false일 때 실행 내용을 작성할 수 있다.

 

 

 

 

- 확인을 누르면 이동하고 취소를 누르면 이동이 되지 않음.

 

 

 

 

 

ㅁ 제출버튼 클릭시에도 기본적으로 사용자가 입력한 값을 서버측으로 전송하면서 요청을 보내는 기본 이벤트가 있다.

- 그런데 무작정 제출되면 안된다.

두 비밀번호가 일치할 때만 기본이벤트가 동작하고 일치하지 않으면 기본이벤트가 동작하지 않도록 한다.

- 입력 형식을 구성했을 때는 사용자가 유효한 형식으로 입력을 했는지 먼저 검수해야 한다.

검수해서 맞다면 제출, 맞지 않다면 제출이 안 되게 막아야 한다.

(유효한 값으로 입력했는지 유효성 체크)

- form 태그 내의 submit 버튼의 기능을 제어한다. 

기본 이벤트를 가지고 있기 때문에 어떤 경우에는 기본 이벤트가 수행되지 않도록 막아야 한다.

 

 


        document.getElementById("submit").addEventListener("click", evt => {
            // 두 비밀번호가 일치하지 않을 경우 알람창 출력후 디폴트이벤트 막기

            const userPwdInput = document.getElementById("userPwd");         //   value 값이 아닌 input 요소 객체 자체
            const checkPwdInput = document.getElementById("checkPwd");    //   value 값이 아닌 input 요소 객체 자체

            if( userPwdInput.value != checkPwdInput.value ) {
 
                alert("비밀번호가 일치하지 않습니다. 다시 입력해주세요");
                checkPwdInput.focus();
                evt.preventDefault();                    //      기본이벤트가 동작하지 않도록 막기
 
            }
        })
 

 

- id가 submit인 버튼 요소 선택 후, 클릭 이벤트 발생시 동작할 이벤트 핸들러 할당하기.

- alert로 사용자에게 왜 안되는지 알려주는 것이 좋다.

- 보통 이렇게 일치하지 않을 경우 비밀번호 확인 쪽에 포커싱이 되게 해서 다시 입력을 유도한다.

특정 인풋 요소에 포커싱 효과를 주고 싶다면 focus 메소드를 호출하면 된다.

이러면 사용자가 보다 편하게 다시 입력할 수 있게끔 비밀번호 확인 인풋 요소가 바로 선택되어진다.

 

 

 

 

 

ㅁ form에서 유효성 체크로 두 개의 비밀번호가 일치하는지만 확인했다.

- 그런데 사실은 아이디도 유효한 형식인지 확인해야 한다.

- 아이디도 유효한 형식이 아닌 경우 제출 자체가 안되게 해야 한다.

비밀번호 검수 전에 원래는 아이디 체크도 해줘야 한다.

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   

    <h2>디폴트 이벤트</h2>

    <a id="naver-link" href="http://www.naver.com" target="_blank">네이버로 이동</a>
    <br><br>

 
    <form action="/server/test.do" method="get">
        아이디 : <input type="text" name="userId" id="userId"> <br>
        비밀번호 : <input type="password" name="userPwd" id="userPwd"> <br>
        비밀번호 확인 : <input type="password" id="checkPwd"> <br><br>
        <input type="submit" id="submit">
    </form>

 
    <script>


        document.getElementById("submit").addEventListener("click", evt => {
       
            // 아이디가 영문 또는 숫자로만 5글자이상 12글자 이하로 이루어져있는지 체크
            const userId = document.getElementById("userId").value;

           
            if(userId.length >= 5 && userId.length <= 12){

                // 아이디의 글자 수가 맞다면 글자 안의 각각의 글자들이 영문 또는 숫자로만 이루어져 있는지 체크
                for(let i=0; i<userId.length; i++){

                        if(userId.charAt(i) >= 0 && userId.charAt(i) <= 9           // 문자를 뽑아서 숫자인지 체크
                            || userId.charAt(i) >= 'a' && userId.charAt(i) <= 'z'    // 문자를 뽑아서 소문자인지 체크
                            || userId.charAt(i) >= 'A' && userId.charAt(i) <= 'Z'   // 문자를 뽑아서 대문자인지 체크
                        ) {

                        }
                        else {
                            alert("아이디가 틀림");
                            evt.preventDefault();
                        }

                }

            }
            else {
                alert("아이디가 틀림");
                evt.preventDefault();
            }
     
    })



    </script>

</body>
</html>
 

 

 

- value로 접근하는 경우가 빈번할 것 같아서 이번에는 input 요소의 value 값 자체를 변수에 담았다.

- 아이디가 저 패턴을 만족하는지 굉장히 복잡한 구문을 써야 한다.

- 정규 표현식을 사용하면 훨씬 간결하게 작성할 수 있다.

 

 

 

 

ㅁ 정규 표현식

- 어떤 문자열이 특정 패턴을 가지고 있는지 확인하기 위한 표현식.

- 사용자가 입력한 값(아이디, 비번, 이메일, 전화번호 등)이 특정 패턴을 만족하는지 자주 비교한다. 

- 자바스크립트에서만 쓰이는 것이 아니다.

자바와 오라클에도 특정 패턴을 제시할 때 이 정규식을 쓸 수 있다.

 

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   

    <h2>디폴트 이벤트</h2>

    <a id="naver-link" href="http://www.naver.com" target="_blank">네이버로 이동</a>
    <br><br>

 
    <form action="/server/test.do" method="get">
        아이디 : <input type="text" name="userId" id="userId"> <br>
        비밀번호 : <input type="password" name="userPwd" id="userPwd"> <br>
        비밀번호 확인 : <input type="password" id="checkPwd"> <br><br>
        <input type="submit" id="submit">
    </form>

 
    <script>


        document.getElementById("submit").addEventListener("click", evt => {
       
            // 아이디가 영문 또는 숫자로만 5글자이상 12글자 이하로 이루어져있는지 체크
            const userId = document.getElementById("userId").value;

           
            let idRegExp = /^[a-zA-Z0-9]{5,12}$/;      // 정규 표현식 (공백 있으면 안 됨)

            if( !idRegExp.test(userId) ) {   // 사용자가 입력한 값이 저 패턴을 만족하지 않는 경우

                alert('아이디를 잘못 입력하셨습니다.');
                evt.preventDefault();  //  기본 이벤트 수행 막기

            }

       
        })



    </script>

</body>
</html>
 

 

 

- 양 옆에 슬래시( / )를 긋고 안 쪽에 내가 앞으로 비교할 패턴을 써둘 수 있다.

- 이때 대괄호 블록에 a-z, A-Z, 0-9 를 써서 허용 가능한 문자들의 목록을 나열했다.

영문이랑 숫자 목록을 나열한 것이다.

- 그리고 이 목록에 해당하는 값이 5글자 이상, 12글자 이하인지를 비교할 정규 표현식이라는 것을 작성했다.

- 이렇게 정규 표현식을 작성하면 사용자가 입력한 값이 이 패턴을 만족하는지를 비교해볼 수 있다.

 

 

- 정규 표현식.test(문자열)라는 메소드로 비교할 문자열을 제시할 수 있다.

- 사용자가 입력한 아이디 값이 저 패턴을 만족하면 true, 아니면 false를 반환한다.

- 아이디를 체크하고 비밀번호 체크도 이어서 진행하는데

아이디가 잘못 입력되었다면 비밀번호 체크를 할 필요가 없다.

그래서 return;으로 함수를 강제종료한다.