-
자바스크립트 - Event 이벤트 핸들러프로그래밍/JavaScript 자바스크립트 2021. 10. 2.반응형
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <script type="text/javascript"> function fun1() { alert("fun 1..."); } function fun2() { alert("fun 2..."); } </script> </head> <body> <h3>event handler</h3> <p> - 이벤트 핸들러 : 이벤트가 발생했을 때 그 처리를 담당하는 함수<br> - 이벤트 등록 인라인 이벤트 핸들러 방식 : on으로 시작(onclick)하는 이벤트 속성값으로 이벤트 호출 </p> <p> <button type="button" onclick="fun1();">클릭 1</button> </p> <p> <button type="button" onclick="fun1(); fun2();">클릭 2</button> </p> </body> </html>
인라인 태그에서 이벤트 핸들러를 추가하려면 onclick를 사용하면 된다.
버튼 태그 인라인에서 onclick = "fun1(); fun2()" 버튼을 누르면 펀함수1과 2를 실행해라
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> </head> <body> <h3>event handler</h3> <p> 이벤트 등록 : 이벤트 핸들러 프로퍼티 방식</p> <p> <button type="button" class="btn">클릭</button> </p> <script type="text/javascript"> const btn = document.querySelector(".btn"); // 이벤트 핸들러 프로퍼티 방식으로 이벤트 등록 // 이벤트 핸들러 프로퍼티 방식은 하나의 이벤트 핸들러만 등록가능하며, 다시 등록하면 기본 이벤트는 덮어 쓴다. btn.onclick = function() { alert("클릭 1"); }; // 위에 있는 "클릭 1"은 실행되지 않는다. btn.onclick = function() { alert("클릭 2"); }; </script> </body> </html>
이벤트 핸들러는 하나만 가능하다. 만약 이미 있는데 또 이벤트를 만들면 기존의 이벤트는 사라진다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> </head> <body> <h3>event handler : 이벤트 등록 - addEventListener() 메소드</h3> <p> <button type="button" class="btn">클릭</button> </p> <script type="text/javascript"> const btn = document.querySelector(".btn"); // addEventListener() 메소드로 이벤트 등록 btn.addEventListener("click", function(){ alert("클릭 1"); }); // 둘다 실행 btn.addEventListener("click", function(){ alert("클릭 2"); }); </script> </body> </html>
이벤트 핸들러를 자바스크립트에서 따로 등록(추가) 해줄 수 있다.
먼저 쿼리 셀렉터로 이벤트를 줄 버튼의 클래스명을 넣어주고
.addEventListener() 를 이용해서 이벤트를 추가한다.
"click"은 말그대로 클릭 이벤트를 준다는 뜻이고, 클릭 했을때 일어나는 이벤트를 메소드로 정해준다.
만약 같은 곳에 이벤트를 여러개 등록하면 등록한 이벤트 전부 실행 된다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <script type="text/javascript"> function sub(obj) { alert('한번만...'); // button의 click 이벤트 제거 obj.removeAttribute("onclick"); } </script> </head> <body> <h3>event handler - 등록된 이벤트 제거</h3> <p> 인라인 이벤트 핸들러 </p> <p> <button type="button" onclick="sub(this);">확인</button> </p> <hr> <p> 이벤트 핸들러 프로퍼티 방식 </p> <p> <button type="button" id="btn1">확인</button> </p> <script type="text/javascript"> const btn1 = document.getElementById("btn1"); btn1.onclick = function() { alert("한번만 실행합니다."); btn1.onclick = null; }; </script> <hr> <p> addEventListener() </p> <p> <button type="button" id="btn2">등록</button> <button type="button" id="btn3">제거</button> </p> <script type="text/javascript"> var fn = function() { alert("방가워요..."); }; const btn2 = document.getElementById("btn2"); const btn3 = document.getElementById("btn3"); // 이벤트 등록 btn2.addEventListener("click", fn); // 이벤트 제거 btn3.addEventListener("click", function(){ btn2.removeEventListener("click", fn); }); </script> </body> </html>
이벤트 핸들러를 제거하려면 add를 remove로 바꾸면 된다.
형식은 똑같고 removeEventListener("어떤 기능 없앨건지", 어떤 메소드를 없앨건지)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <script type="text/javascript"> function sub() { // 이벤트를 발생 시킨 객체 var obj = event.srcElement; // 이벤트를 발생시킨 태그 var t = obj.tagName; // 이벤트를 발생시킨 객체의 id var i = obj.id; // 이벤트를 발생시킨 객체의 innerText var s = obj.innerText; var result = "태그명:"+t+"<br>"; result+="id:"+i+"<br>"; result+="텍스트내용:"+s+"<br>"; // document.getElementById("layout").innerText = result; document.getElementById("layout").innerHTML = result; } </script> </head> <body> <h3> 이벤트를 발생 시킨 객체 </h3> <p> <button type="button" onclick="sub()" id="btn1">자바</button> | <button type="button" onclick="sub()" id="btn2">스프링</button> | <button type="button" onclick="sub()" id="btn3">오라클</button> </p> <div id="layout"></div> </body> </html>
이벤트를 발생시킨 객체도 알아낼 수 가 있는데
event.srcElement를 사용하면 알아 낼 수 있다.
event.srcElement.tagName = 태그 이름
event.srcElement.id = id 이름
event.srcElement.innerText = 텍스트 내용 ex)자바 / 스프링 / 오라클
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box1 { background: #ccc; padding: 20px; display: block; } .box2 { background: #aaa; padding: 20px; display: block; } .box3 { background: #888; padding: 20px; display: block; } .console { background: #47a; padding: 20px; margin: 50px; } </style> </head> <body> <h3> preventDefault() </h3> <p> - a href 속성 : a 태그를 클릭하면 href 속성에 설정된 해당 페이지로 이동 <br> - a 태그 : click 이벤트가 존재하면 먼저 click를 처리하고 href 페이지로 이동<br> - preventDefault() : 이벤트를 취소 할 수 있는 경우 취소하지만, 상위로의 이벤트는 전파 된다. </p> <hr> <div class="box1"> DIV 영역 <p class="box2"> P 영역 <a class="box3" href="https://google.com" target="_blank">A 영역</a> </p> </div> <hr> <div class="console"><br></div> <script type="text/javascript"> const box1 = document.querySelector(".box1"); const box2 = document.querySelector(".box2"); const box3 = document.querySelector(".box3"); const console = document.querySelector(".console"); // div에 click 이벤트 설정 box1.addEventListener('click', function(){ console.innerHTML += "<br>div 클릭"; }); // p에 click 이벤트 설정 box2.addEventListener('click', function(){ console.innerHTML += "<br>p 클릭"; }); // a에 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>a 클릭"; // 이벤트의 기본 동작을 중단. href 속성을 무효화 event.preventDefault(); // 상위로 이벤트는 전파 된다. }); </script> </body> </html>
preventDefault()는 이벤트의 동작을 중단 시킨다.
즉 a 키를 눌러서 사이트 이동이 이루어지는 이벤트를 멈춘다 하지만 상위로에게는 이벤트가 전파가 된다
고유 동작을 중지 시키는것이지 이벤트 자체를 전부 중단은 아님
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box1 { background: #ccc; padding: 20px; display: block; } .box2 { background: #aaa; padding: 20px; display: block; } .box3 { background: #888; padding: 20px; display: block; } .console { background: #47a; padding: 20px; margin: 50px; } </style> </head> <body> <h3> stopPropagation() </h3> <p> - stopPropagation() : 상위로 이벤트가 전파되는 것을 막는다. </p> <hr> <div class="box1"> DIV 영역 <p class="box2"> P 영역 <a class="box3" href="https://google.com" target="_blank">A 영역</a> </p> </div> <hr> <div class="console"><br></div> <script type="text/javascript"> const box1 = document.querySelector(".box1"); const box2 = document.querySelector(".box2"); const box3 = document.querySelector(".box3"); const console = document.querySelector(".console"); // div에 click 이벤트 설정 box1.addEventListener('click', function(){ console.innerHTML += "<br>div 클릭"; }); // p에 click 이벤트 설정 box2.addEventListener('click', function(){ console.innerHTML += "<br>p 클릭"; }); // a에 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>a 클릭"; // href 속성은 무효화 되지 않으며, 상위로의 이벤트는 전파되지 않는다. event.stopPropagation(); }); </script> </body> </html>
event.stopPropagation()은 상위로도 이벤트가 전송이 안된다.
이벤트 고유 동작과 상위로에 전파도 막으니까 이벤트 전부를 막을 수 있다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box1 { background: #ccc; padding: 20px; display: block; } .box2 { background: #aaa; padding: 20px; display: block; } .box3 { background: #888; padding: 20px; display: block; } .console { background: #47a; padding: 20px; margin: 50px; } </style> </head> <body> <h3> bubbling과 capturing </h3> <p> bubbling : 하위요소에서 이벤트가 발생하면 하위요소에서 상위요소로 이벤트가 전파(기본)<br> capturing : 하위요소에서 이벤트가 발생하면 상위요소에서 하위요소로 이벤트가 전파 </p> <hr> <div class="box1"> DIV 영역 <p class="box2"> P 영역 <span class="box3">SPAN 영역</span> </p> </div> <hr> <div class="console"><br></div> <script type="text/javascript"> const box1 = document.querySelector(".box1"); const box2 = document.querySelector(".box2"); const box3 = document.querySelector(".box3"); const console = document.querySelector(".console"); /* // - bubbing(기본) // span을 클릭하면 : span 클릭 - p 클릭 - div 클릭 // div에 click 이벤트 설정 box1.addEventListener('click', function(){ console.innerHTML += "<br>div 클릭"; }, false); // 기본 false // p에 click 이벤트 설정 box2.addEventListener('click', function(){ console.innerHTML += "<br>p 클릭"; }); // span에 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>span 클릭"; }); */ // - captuing // span을 클릭하면 : div 클릭 - p 클릭 - span 클릭 // div에 click 이벤트 설정 box1.addEventListener('click', function(){ console.innerHTML += "<br>div 클릭"; }, true); // p에 click 이벤트 설정 box2.addEventListener('click', function(){ console.innerHTML += "<br>p 클릭"; }, true); // span에 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>span 클릭"; }, true); </script> </body> </html>
bubbling 과 capturing
버블링은 이벤트가 제일 깊은 곳에 있는 요소에서 부터 시작을해서 모든 부모 요소를 거슬러 올라가면서
이벤트들을 발생 시킨다.
그렇기 때문에
여기서 span 영역을 한번만 클릭해도 부모 요소인 p랑 div의 영역까지 순차적으로 거슬러 올라가면서 이벤트를 발생 시킨걸 볼 수 있다.
capturing은 bubbling과 반대다.
캡쳐링도 똑같이 하위요소에서 이벤트가 발생하면 위로 요소가 전파가 되는데 버블링과는 다르게 상위 요소부터 하위요소로 전파가 된다.
똑같이 span 영역을 한번 클릭 했을때 버블링은 순차적으로 거슬러 올라 갔다면
캡쳐링은 가장 바깥쪽 부모부터 순차적으로 내려오면서 이벤트가 발생된다.
버블링이냐 캡쳐링이냐는 어떻게 설정 하냐면
아무것도 옵션을 안주면 버블링(기본 상태)이고
box1.addEventListener('click', function(){
console.innerHTML += "<br>div 클릭";
}, true); 여기서 뒤에 addEventListener 3번째 부분에 true를 주게 되면 이게 캡쳐링이다.<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box1 { background: #ccc; padding: 20px; display: block; } .box2 { background: #aaa; padding: 20px; display: block; } .box3 { background: #888; padding: 20px; display: block; } .console { background: #47a; padding: 20px; margin: 50px; } </style> </head> <body> <h3> stopImmediatePropagation() </h3> <hr> <div class="box1"> DIV 영역 <p class="box2"> P 영역 <span class="box3">SPAN 영역</span> </p> </div> <hr> <div class="console"><br></div> <script type="text/javascript"> const box1 = document.querySelector(".box1"); const box2 = document.querySelector(".box2"); const box3 = document.querySelector(".box3"); const console = document.querySelector(".console"); // div에 click 이벤트 설정 box1.addEventListener('click', function(){ console.innerHTML += "<br>div 클릭"; }); // p에 click 이벤트 설정 box2.addEventListener('click', function(){ console.innerHTML += "<br>p 클릭"; }); // span에 첫번째 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>span 클릭-1"; // event.stopPropagation(); // 상위로 이벤트가 전파되지 않지만 같은 레벨의 이벤트는 처리됨 // 상위로 이벤트가 전파되지 않으며, 같은 레벨의 이벤트도 처리되지 않도록 중지 한다. event.stopImmediatePropagation(); }); // span에 두번째 click 이벤트 설정 box3.addEventListener('click', function(){ console.innerHTML += "<br>span 클릭-2"; }); </script> </body> </html>
stopImmediatePropagation()를 사용하면 그 뒤로 예정 중이던 이벤트도 모두 중지된다.
간단하게 stopImmediatePropagation() 이후로 나오는 모든 이벤트는 중단 된다고 보면 된다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> </head> <body> <h3> 키보드 관련 이벤트 </h3> <p> <input type="text" id="inputs"> </p> <hr> <div id="layout"></div> <hr> <div> <p> - ASCII 키 : a~z, 0~9, 엔터 등<br> 발생하는 이벤트 : keydown - keypress - keyup 순으로 발생<br> keydown, keyup : a나 A를 누르면 keyCode는 65(대소문자 키를 구분 불가)<br> keypress : a키는 97, A키는 65를 keyCode에서 반환(대소문자 코드가 다름)<br> keydown이나 keyup은 어떤키가 눌렀는지만 판단하고 대소문자를 구분하지 않는다.<br> keypress는 실제 눌러진 키코드를 반환한다. </p> <p> - F11 ~ F12, Alt, Ctrl, Shift등 특수 키<br> 발생하는 이벤트 : keydown - keyup 순으로 발생(keypress 이벤트는 발생되지 않는다.)<br> - shift+a 키는 누를 경우 발생하는 이벤트<br> keydown(shift) - keydown(a) - keypress(a) - keyup(a) - keyup(shift) 순으로 이벤트 발생 </p> </div> <script type="text/javascript"> var inputs = document.getElementById("inputs"); var layout = document.getElementById("layout"); inputs.onkeydown = function(e) { var code = e.keyCode; // 눌러진 키의 ASCII 코드값 var s = "keydown : " + code; layout.innerHTML = s; }; inputs.onkeypress = function(e) { var code = e.keyCode; var s = "<br>onkeypress : " + code; layout.innerHTML += s; }; inputs.onkeyup = function(e) { var code = e.keyCode; var s = "<br>onkeyup : " + code; layout.innerHTML += s; }; </script> </body> </html>
keyCode는 어떤 키 값에 대한 값을 ASCII 코드로 보여준다.
하지만 keydown, keyup은 대소문자를 구분 못하기 때문에
keypress를 통해서 알아내야 하며
키보드가 눌리는 순서는 keydown - keypress - keyup 순이다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <script type="text/javascript"> function onlyNumber() { if( event.keyCode < 48 || event.keyCode > 57 ) { event.preventDefault(); // 이벤트 취소 } } function onlyAlphabet() { if( (event.keyCode < 65 || event.keyCode > 90) && (event.keyCode < 97 || event.keyCode > 122) ) { event.preventDefault(); } } function onlyHangul() { if( event.keyCode < 12592 || event.keyCode > 12687 ) { event.preventDefault(); } } function notHangul(obj) { // bs:8, tab:9, %:37, ':39, .:46 if(event.keyCode==8||event.keyCode==9||event.keyCode==37|| event.keyCode==39||event.keyCode==46) { return; } // 자음, 모음, 한글을 지움 obj.value = obj.value.replace(/[ㄱ-ㅎㅏ-ㅣ가-힣]/g, ''); } </script> </head> <body> <h3>keyboard Event</h3> <p> 숫자만 : <input type="text" onkeypress="onlyNumber();" onkeyup="notHangul(this);"> </p> <p> 영문자만 : <input type="text" onkeypress="onlyAlphabet();" onkeyup="notHangul(this);"> </p> <p> 한글만 : <input type="text" onkeypress="onlyHangul();"> </p> </body> </html>
아까 배웠던 이벤트를 취소 시키는 preventDefault()를 활용하면 특정 키 들을 입력 못하게 막을 수 있다.
정규식과 같이쓰면 아예 영문자나 숫자만 쓰게 만든다거나 가능함.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box { width: 150px; height: 100px; border: 3px dotted #333; } </style> <script type="text/javascript"> function right_click() { if( event.button == 2 || event.button == 3) { alert('우측 클릭 금지 상태'); } } document.onmousedown = right_click; </script> </head> <body> <h3>마우스</h3> <div class="box" onmouseover="this.style.background='#ff0';" onmouseout="this.style.background='';"> </div> </body> </html>
그리고 이벤트를 활용해서 마우스 우측 금지 시킬 수 있다. 우클릭 금지
어떤 사이트들을 가보면 마우스 우측 클릭 자체가 안되거나 우측을 클릭하면 우측 클릭 금지라고 나오는 사이트 들이 있는데
이건 전부 이벤트를 활용해서 만든 것.
현재 document.onmousedown에 메소드를 줘서 도큐먼트 문서 전체에 영향력이 있는 모습
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <script type="text/javascript"> function changeEmail() { var f = document.memberForm; var s = f.selectEmail.value; if(s != 'direct') { f.email2.value = s; f.email2.readOnly = true; f.email1.focus(); } else { f.email2.value = ""; f.email2.readOnly = false; f.email1.focus(); } } </script> </head> <body> <form name="memberForm"> <p> <select name="selectEmail" onchange="changeEmail();"> <option value="">:: 선택 ::</option> <option value="naver.com">네이버 메일</option> <option value="gmail.com">지 메일</option> <option value="hanmail.com">한 메일</option> <option value="nate.com">네이트 메일</option> <option value="direct">직접입력</option> </select> <input type="text" name="email1"> @ <input type="text" name="email2" readonly="readonly"> </p> </form> </body> </html>
이벤트를 이용해서 선택창에서 원하는 목록을 선택하면 그걸 text 박스로 옮겨줌
onchange 함수는 내용이 변경된걸 감지하는 함수임
셀렉트문의 값이 바뀐다면 자바스크립트에서 만들어논 changeEmail() 함수를 실행
email2 텍스트 박스에 바뀐 selectEmail 값을 넣어줌
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .box { width: 300px; height: 300px; margin: 30px auto; border: 3px dotted gray; } </style> <script type="text/javascript"> function init() { var layout = document.querySelector(".box"); layout.onmouseover = function(){ layout.style.background = '#ff0'; }; layout.onmouseout = function(){ layout.style.background = ''; }; } // init(); // 에러. document.querySelector(".box")를 찾지 못하므로 // load : 스타일등 모든 리소스를포함하여 전체 페이지가 로드되면 이벤트가 시작 /* window.addEventListener("load", function(){ init(); }); */ window.addEventListener("load", ()=>init()); </script> </head> <body> <div class="box"></div> </body> </html>
window.addEventListener("load", ()=>init());
화살표 표현식으로 람다와 유사한 자바스크립트 문법
해석하자면 이 인터넷창이 뜰때 load를 한다.(스타일이나 모든 리소스를 포함해서 전체 페이지가 로드 될때까지 기다림)
그리고 로드가 되면 function() 함수 init()를 실행 시킨다. 라는 뜻.
init() 함수는 HTML의 .box 클래스를 상속 받는 놈을 찾아서 그놈한테 마우스를 올리면(onmouseover 이벤트) function()을 실행 시키는데 이 function의 기능은 배경색을 노랑색으로 바꾸는것.
반대로 마우스가 벗어나면 (onmouseout 이벤트) 메소드 실행을 하는데 이 메소드는 배경을 다시 하얗게 바꾼다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="icon" href="data:;base64,iVBORw0KGgo="> <style type="text/css"> .wb { background: white; border: 1px solid #333; } .yb { background: yellow; border: 1px solid tomato; outline: none; } </style> <script type="text/javascript"> function inputsFocus(obj) { obj.className = "yb"; } function inputsBlur(obj) { obj.className = "wb"; } </script> </head> <body> <form action=""> <p> <label>이름 : <input type="text" name="name" class="wb" onfocus="inputsFocus(this);" onblur="inputsBlur(this);"></label> </p> <p> <label>패스워드 : <input type="password" name="pwd" class="wb" onfocus="inputsFocus(this);" onblur="inputsBlur(this);"></label> </p> <p> <label>나이 : <input type="text" name="age" class="wb" onfocus="inputsFocus(this);" onblur="inputsBlur(this);"></label> </p> <p> <button type="button">check</button> </p> </form> </body> </html>
이벤트를 활용해서 text 박스에 focus가 일어나면 (활성화) 이벤트를 주는 내용이다.
그때 사용하는 text 박스 이벤트는 onfocus와 onblur이다 이름으로 알 수 있듯이.
onfocus는 text 박스 활성화가 되었을때 일어나는 이벤트고
onblur는 text 박스에서 비활성화 되어있을때 일어난다.
태그 내에서 (인라인) 메소드 인자에 this를 주는 이유는 이벤트 발생시 자기 자신을 부르기 때문이다.
자기자신 즉 자신의 text 박스의 클래스 이름을 바꾼다는 뜻.
반응형'프로그래밍 > JavaScript 자바스크립트' 카테고리의 다른 글
자바스크립트 - 정규식 (0) 2021.10.06 자바스크립트 - Form 폼 (양식) / 예제 (0) 2021.10.06 자바스크립트 - navigator (0) 2021.10.01 자바스크립트 - 화면 좌표 찾기 (0) 2021.10.01 자바스크립트 - form에 접근하기 (0) 2021.10.01