Web/JavaScript

11. 이벤트(Event)

사라리24 2024. 4. 18. 16:55

1. 이벤트(Event)

웹브라우저가 알려주는 HTML 요소에 대한 사건이 발생
웹페이지에 사용된 자바스크립트는 발생한 이벤트에 반응하여 특정 동작을 수행
자바스크립트는 비동기식 이벤트 중심의 프로그래밍 모델
이벤트가 순차적으로 발생하지 않음(파이썬과 다름)

 


          
               <input type ="button"   onclick   =  "sendit()"   value="확인">
                                             --------        --------         --------
                                   이벤트 타겟   이벤트 타입    이벤트 리스너


               <button type="button" onclick  =  "sendit()"> 확인 </button>  
                                            -----------    ---------         ---------
                                         이벤트 타겟   이벤트 타입   이벤트 리스너  


 
  • button: 이벤트 타겟
  • sendit(): 이벤트 리스너
  • onclick: 이벤트 타입
이벤트 타겟
(Event Target)
이벤트가 일어날 객체
이벤트 타입
(Event Type)
발생한 이벤트의 종류를 나타내는 문자열로 이벤트명(Event Name)이라고도 함
키보드, 마우스, HTML DOM, window 객체 등을 처리하는 이벤트를 제공
이벤트 리스터
(Event Listener)
이벤트가 발생했을 때 그 처리를 하는 함수
이벤트 핸들러라고도 부름
지정된 타입의 이벤트가 특정 요소에서 발생하면 웹브라우저는 그 요소에 등록된 이벤트리스너를 실행
이벤트 등록 객체.addEventListener(이벤트타입, 이벤트리스너);
이벤트 제거 객체.removeEventListener(이벤트타입, 이벤트리스너);

 

  • 예제1

        < head >

                  <script>     

                 window.onload=function(){
                     const text=document.getElementById('text');
                     text.innerHTML= "<strong style='color:deeppink;'>
                                                         HTML 문서가 모두 로드되었습니당</strong style>
";
                 }
                 function changeText(el){
                         // el = document.getElementById('p')
                         el.innerHTML="<b style='color:deepskyblue;'> 문자열이 변경되었니다</b>"
                     }
 
                   </script>     
   
        </ head >

        <body>

                 <h2> 
이벤트 타입 </h2>
                 <p id="text"></p>
                 <p onclick="changeText(this)"> 문자열을 클릭하세용 </p>
                 <!-- this: p태그 자기 자신, p태그를 매개변수로 넘긴거임 -->
 
        </body>

 




<html> 실행시


<문자열을 클릭하세용> 클릭
  • 예제2
 
        < head >

                   <script>   

                         let btn; //전역으로 빼주기

                         window.onload=function(){
                             btn = document.getElementById('eventBtn')
                             btn.addEventListener('click',clickBtn); //('이벤트 타입',이벤트 핸들러_콜백함수)
                             btn.addEventListener('mouseover',mouseOverBtn);
                             btn.addEventListener('mouseout',mouseOutBtn);

                             const delbtn = document.getElementById('delBtn');
                             delbtn.addEventListener('click',delEvent);
                         }
                         function clickBtn(){
                             document.getElementById('text').innerHTML                
                            ='<strong>버튼을 클릭했어용</strong>';

                         }
                         function mouseOverBtn(){
                              document.getElementById('text').innerHTML                 
                              ='<strong>버튼 위에 커서가 올라갔어요!</strong>'
                         }
                         function mouseOutBtn(){
                             document.getElementById('text').innerHTML
                             ='<strong>버튼 밖으로 커서가 나갔어요</strong>'
                         }

                         function delEvent(){
                             // const btn=document.getElementById('eventBtn'); (원래자리)
                             btn.removeEventListener('click',clickBtn);
                             btn.removeEventListener('mouseover',mouseOverBtn);
                             btn.removeEventListener('mouseout',mouseOutBtn);
                             document.getElementById('text').innerHTML
                             ='<strong>이벤트 핸들러가 모두 삭제되었어요 </strong>'
                         }

                   </script>         

       <  /head  >

        <body>

                  <h2> 
이벤트 리스너</h2>

                   <p><button id="eventBtn">이벤트 버튼</button>               
                   <button id="delbutton" onclick="delEvent()">이벤트 삭제 버튼</button></p>
                   <p id="text"></p>

     
        </body>






 window.onload=function()


btn.addEventListener('click',clickBtn);
function clickBtn()



btn.addEventListener('mouseover',mouseOverBtn);
function mouseOverBtn()



btn.addEventListener('mouseout',mouseOutBtn);
function mouseOutBtn()



function delEvent()


 

 

2. 이벤트 객체(Event Object)


- 특정 타입의 이벤트와 관련이 있는 객체
- 이벤트 객체는 해당 타입의 이벤트에 대한 상세 정보를 저장하고 있음
- 모든 이벤트 객체는 이벤트의 타입을 나타내는 type 프로퍼티와 이벤트 대상을 나타내는 target 프로퍼티를 가지고 있음
- 이벤트 객체를 이벤트 리스너가 호출할 때 인수로 전달

 

  • 기본형식


            
                 <button type="button" id="btn" onclick="sendit()" value="확인">완료</button>

                 <script>

                     function sendit(e) {
                         ...
                         e.target => button
                         e.type => click
                         e.target.id => btn
                         e.target.value => 확인
                     }

                 </script>


 

 

  • 이벤트 객체 출력해보기


        <head>

                   <script>     

                     window.onload=function(){
                         const btn=document.getElementById('btn');
                         btn.addEventListener('click',clickBtn);
                     }
                     function clickBtn(e){ //event 객체 저장
                         //매개변수 넘기지 없어도 자동으로 이벤트 객체가 만들어짐
           
                         console.log(e);  // PointerEvent
                         console.log(e.target); //<button type="button" id="btn" value="확인">확인</button>
                         console.log(e.target.id);  //btn
                         console.log(e.target.value); //확인
                         console.log(e.type);    //click
                     }
                    </script>     

        </head>

     
        <body>

                 <h2>
이벤트객체1 </h2>

              <button type="button" id="btn" value="확인">확인</button>
 
        </body>

 

 

  • 문제

버튼 2개를 아래와 같이 만들고 각 버튼을 누르면 콘솔에 출력하는 문서를 만들어보자.
(단, 이벤트 객체를 이용하여 버튼을 구별한다.)


      [버튼1] [버튼2]


-버튼1: 버튼1이 눌렸어용
-버튼2: 버튼2가 눌렸어용



        <head>

                  <script>     

                       window.onload=function(){
                           const btn1=document.getElementById('btn1');
                           btn1.addEventListener('click',clickBtn);
                           const btn2=document.getElementById('btn2');
                           btn2.addEventListener('click',clickBtn);
                           const btn3=document.getElementById('btn3');
                           btn3.addEventListener('click', (e) => {
                               console.log('버튼 3이 눌렸어요!');
                       });
                       }
                       function clickBtn(e){
                           switch(e.target.id){
                               case 'btn1':
                                   console.log('버튼1이 눌렸어요!');
                                   break;
                               case 'btn2':
                                   console.log('버튼2가 눌렸어요!');
                                   break;
                           }
                       }
 
                 </script>    

        </head>
     
        <body>

                 <h2> 
이벤트객체2</h2>

                   <button type="button" id="btn1">버튼1</button>
                   <button type="button" id="btn2">버튼2</button>
                   <button type="button" id="btn3">버튼3</button>
 
        </body>


 









 

  • 회원가입에 이벤트 객체 추가하기

     
        <body>

                  <script>     

               <script src="./js/regist.js" defer></script>
               <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
 
                  </script>     

                 <h2>  회원가입 </h2>

          <form action="/regist" name="regform" id="regform" method="post" onsubmit="return sendit()">

                <input type="hidden" name="ssncheck" id="ssncheck" value="n">
                 <p>아이디: <input type="text" name="userid" id="userid" maxlength="20"></p>
                 <p>비밀번호: <input type="password" name="userpw"         
                     id="userpw" maxlength="20"></p>
                 <p>비밀번호 확인: <input type="password" name="userpw_re"       
                     id="userpw_re" maxlength="20"></p>
                 <p>이름: <input type="text" name="name" id="name" maxlength="10"></p>
                 <p>휴대폰번호: <input type="text" name="hp" id="hp" maxlength="20"></p>
                 <p>이메일: <input type="text" name="email" id="email" maxlength="50"></p>
                 <p>성별: <label for="male">남자</label>
                 <
input type="radio" name="gender" value="남자" checked>
                 <label for="female">여자</label>
                 <
input type="radio" name="gender" value="여자"></p>

                 <p>주민등록번호: <input type="text" name="ssn1" id="ssn1" maxlength="6" class="ssn" >
                   - 
<input type="password" name="ssn2" id="ssn2" maxlength="7" class="ssn" >
                    
<button type="button" onclick="checkSSN()" id="checkbtn" >
                주민등록번호 검증</button></p>

                 <p>우편번호: <input type="text" name="zipcode" maxlength="5" id="sample6_postcode"
                       
placeholder="우편번호"> <button type="button" 
                       onclick="sample6_execDaumPostcode()"> 우편번호 찾기</button></p>

                 <p>주소: <input type="text" name="address1" id="sample6_address"          
                     placeholder="주소"></p>
                 <p>상세주소: <input type="text" name="address2" id="sample6_detailAddress"       
                     placeholder="상세주소"></p>
                 <p>참고항목: <input type="text" name="address3" id="sample6_extraAddress" 
                     placeholder="참고항목"></p>
                 <p><button type="submit">가입완료</button> <button type="reset">다시작성</button></p>

    </form>

 
 
        </body>




 

 

  • 주민번호 칸 넘어가기
    : 회원가입 페이지에서 주민등록번호 앞자리를 입력하면 자동으로 뒷자리로 포커스 이동
더보기
window.onload=function(){
    const ssn1=document.getElementById('ssn1');
    ssn1.addEventListener('keyup',()=> {
        if(ssn1.value.length >= 6){
            document.getElementById('ssn2').focus();
        }
    })
}

 

 

  • 주민번호 칸  유효성 검사
    - 주민등록번호를 입력하지 않았다면 체크 -> 주민등록번호를 수정하면 hidden의 value를 n으로 변경
    - 유효성 검사를 통과하면 hidden의 value를 n에서 y로 변경
더보기
window.onload=function(){
    const ssn=document.querySelectorAll('.ssn');
    ssn.forEach((s)=>{
        //console.log(s); //두 객체가 찍힘
        s.addEventListener('input',()=>{ //글자 입력창이 발생했을 때 익명함수 실행
            document.getElementById('ssncheck').value='n'; //checkssn -> n 으로 바꿔라
        })
    })
}
function checkSSN(){
    if(result == ssn[12]){
        alert('유효한 주민등록번호입니다!');
        document.getElementById('ssncheck').value="y";
    }else{
        alert('유효하지 않은 주민등록번호입니다');
    }
}
function sendit(){
if(ssncheck.value == 'n') {
        alert('주민등록번호 유효성검사를 해주세요.');
        checkbtn.focus();
        return false;
    }
    return true;
}

 

* 주민번호 제대로 입력하지 않았을 시 value="n"

 

* 주민번호 제대로 입력했을 시

 

* 확인클릭---- >  value="y"

 

  • JavaScript  전체코드
더보기
         
      
 
                 window.onload = function(){

                    // 주민번호 칸 넘어가기
                     const ssn1 = document.getElementById('ssn1');
                     ssn1.addEventListener('keyup', () => {
                         if(ssn1.value.length >= 6){
                             document.getElementById('ssn2').focus();
                         }
                     });

                     // 폼 객체 value='n'
                     const ssn = document.querySelectorAll('.ssn');
                     ssn.forEach((s) => {
                         // console.log(s);
                         s.addEventListener('input', () => {
                             document.getElementById('ssncheck').value = 'n';
                         })
                     })

                 }

                 // 주민번호 검증함수
                 function checkSSN(){
                     // alert('주민등록 검증함수!');
                     const ssn1 = document.getElementById('ssn1');
                     const ssn2 = document.getElementById('ssn2');

                     const ssn = ssn1.value + ssn2.value;
                     const key = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];

                     let total = 0;

                     for(let i=0; i<key.length; i++){
                         total += parseInt(ssn[i]) * key[i];
                     }
                
                     let result = total % 11;
                     result = 11 - result;
                     if(result >= 10) result = result % 10;

                     if(result == ssn[12]){
                         alert('유효한 주민등록번호입니다!');
                         document.getElementById('ssncheck').value = 'y';
                     }else{
                         alert('유효하지 않은 주민등록번호입니다');
                     }
                 }

                 // 폼 제출완료 함수
                 function sendit(){
                     // alert('폼이 submit 되었음!');
                     const userid = document.getElementById('userid');
                     const userpw = document.getElementById('userpw');
                     const userpw_re = document.getElementById('userpw_re');
                     const name = document.getElementById('name');
                     const hp = document.getElementById('hp');
                     const email = document.getElementById('email');
                     const ssncheck = document.getElementById('ssncheck');
                     const checkbtn = document.getElementById('checkbtn');


                     const expIdText = /^[A-Za-z]{4,20}$/;
                     const expPwText = /^(?=.*[A-Za-z])(?=.*[!@#$%^&*+=-])(?=.*[0-9]).{4,20}$/;
                     const expNameText = /^[가-힣]+$/;
                     const expHpText = /^\d{3}-\d{3,4}-\d{4}$/;
                     const expEmailText = /^[A-Za-z0-9\-\.\_]+@[A-Za-z0-9\-]+\.[A-Za-z]+$/



                     if(!expIdText.test(userid.value)){
                         alert('아이디는 4자이상 20자이하의 영문자로 입력하세요');
                         userid.focus();
                         return false;
                     }

                     if(!expPwText.test(userpw.value)){
                         alert('비밀번호는 4자이상 20자이하의 영문자,숫자,특수문자를 1자이상 꼭 포함해야합니다');
                         userpw.focus();
                         return false;
                     }

                     if(userpw.value != userpw_re.value){
                         alert('비밀번호와 일치하지 않습니다');
                         userpw_re.focus();
                         return false;
                     }

                     if(!expNameText.test(name.value)){
                         alert('이름이 한글이어야 합니다!');
                         name.focus();
                         return false;
                     }

                     if(!expHpText.test(hp.value)){
                         alert('전화번호를 제대로 입력하세요.');
                         hp.focus();
                         return false;
                     }

                     if(!expEmailText.test(email.value)){
                         alert('이메일을 제대로 입력하세요.');
                         email.focus();
                         return false;
                     }

                     if(ssncheck.value == 'n'){
                         alert('주민등록번호 유효성검사를 해주세요');
                         checkbtn.focus();
                         return false;
                     }

                     return true;
                 }
     
 
 

 

 

3. 이벤트 전파(Event Propagation )


이벤트가 발생했을 때 브라우저가 이벤트 리스너를 실행시킬 대상 요소를 결정하는 과정
document 객체나 html 문서의 요소에서 이벤트가 발생하면 대상 요소를 결정하기 위해 이벤트 전파가 일어남

 

  • 버블링 전파방식: 자식에서 부모로 이벤트를 전파
  • 캡쳐링 전파방식: 부모에서 자식으로 이벤트를 전파
    @ 이벤트 전파를 막는 방법 -> 이벤트객체명.stopPropagation()

     
        <body>

                 <h2>  </h2>


                  <script>     

 
                       </script>     

        </body>




 
  • 문제

    - 회원가입 페이지에서 주민등록번호 앞자리를 입력하면 자동으로 뒷자리로 포커스 이동

     
        <body>

                 <h2>  </h2>


                  <script>     

 
                       </script>     

        </body>