[ 이벤트(EVENT) ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <!DOCTYPE html> <head> <meta charset= "utf-8" > <title></title> </head> <!-- [ 이벤트 등록 방식 ] 1. inline 방식 : 이벤트를 이벤트 대상의 태그 속성으로 지정하는 것. - 단점) : 정적인 html과 동적(제어역할)인 javascript를 분리시킬 수 없다. - 장점) : 쉽고, 가독성이 좋다. --> <!-- 자기자신을 참조하는 불편한 방법 --> <input type= "button" id= "target" onclick= "alert('Hello, ' + document.getElementById('target').value);" value= "button" /> <!-- this 를 통해서 간편하게 참조할 수 있다. --> <input type= "button" onclick= "alert('Hello, ' + this.value);" value= "button2" /> <!-- 2. 프로퍼티 리스너를 통한 이벤트 등록 방식 : 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식이다. 장점) : inline방식에 비해 HTML과 Javascript를 분리할 수 있어서 선호되지만, addEventListener 방식을 더욱 추천한다.! --> <input type= "button" id= "target2" value= "button" /> <script type= "text/javascript" > var t = document.getElementById( "target2" ); t.onclick = function (event) { // event객체를 통해서 현재 발생한 이벤트에 대한 // 다양한 정보를 얻을 수 있다. // event의 target속성을 통해 클릭한 객체를 가져올 수 있다. alert( 'Hello, ' + event.target.value); // 하지만, IE8 이하 버전에서는 인자로 event객체를 받지 않아 동작하지 않는다. console.dir(event); // .dir : 객체의 프러퍼티를 보기 쉽게 보여준다. } // 이를 해결하기 위해서는 다음과 같이 하면 된다. t.onclick = function (event) { // IE8이하에서는 첫번째 매개변수로 event를 받지 않아서 window에 있는 event객체 // 를 통해 접근해야한다. 따라서 // event객체가 존재하면 쓰고, 없으면 window.event를 사용한다. var event = event || window.event; // 이때, window.event에서는 target속성이 없고, srcElement속성을 쓴다. // event.target 속성이 존재하면 쓰고, 없으면 event.srcElement속성을 쓴다. var target = event.target || event.srcElement; alert( 'Hello, ' + event.target.value); } </script> <input type= "button" id= "target4" value= "button" /> <input type= "button" id= "target5" value= "button" /> <input type= "button" id= "target6" value= "button" /> <script type= "text/javascript" > // 3. addEventListener를 통해 이벤트를 등록하는 방법 <!-- 위의 방식과 달리, 이 방식은 여러개의 이벤트 핸들러를 등록할 수 있다. 프러퍼티 방식에 onclick에 동일한 메서드를 두번 등록하면 나중에 등록한 메서드만 적용되지만, addEventListener의 경우 동일한 이벤트를 두개 등록할 수 있고 순차적으로 수행되게 된다. --> <input type= "button" id= "target3" value= "button3" /> var t2 = document.getElementById( 'target3' ); t2.addEventListener( "click" , function (event){ alert(1); }); t2.addEventListener( "click" , function (event){ alert(2); }) // 이때, 버튼 클릭시 1과 2 순차적으로 경고창이 뜨게 된다. // t.onclick=function~~를 두번 등록했다면 이후에 등록된 것만 적용될 것이다! // 하지만, addEventListener의 경우도 IE8이하의 버전에서는 동작하지 않는다. // -> IE8이하에서는 attachEvent를 사용해야한다. // 다음은 크로스 브라우징을 고려한 코드이다. var t3 = document.getElementById( 'target4' ); if ( t3.addEventListener ) { // IE8 이상 버전은 // addEventListener가 존재하지 않으면 undefined가 뜰 것이고 js에서 undefined는 // false를 의미한다. t3.addEventListener( "click" , function (event) { alert(event.target.value); }; } else if ( t3.attachEvent ) { // IE8 이하 버전은 t3.attachEvent( "onclick" , function (event) { // attachEvent는 click이 아니라 on을 포함해 써줘야 한다. alert(window.event.srcElement.value); // IE8이하는 매개변수 첫번째에 event객체를 받지 않기 때문 } } // EX) var t4 = document.getElementById( 'target4' ); var t5 = document.getElementById( 'target5' ); function btn_listener(event) { switch ( event.target.id ) { case 'target4' : alert(4); break ; case 'target5' : alert(5); break ; } } t4.addEventListener( "click" ,btn_listener); t5.addEventListener( "click" ,btn_listener); </script> |
[ 이벤트(EVENT)의 전파 및 전파를 막는 방법 ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <head> <style> html{border:5px solid red;padding:30px;} body{border:5px solid green;padding:30px;} fieldset{border:5px solid blue;padding:30px;} input{border:5px solid black;padding:30px;} </style> </head> <fieldset> <legend>event propagation</legend> <input type= "button" id= "target" value= "target" > </fieldset> <script> function handler(event){ var phases = [ 'capturing' , 'target' , 'bubbling' ] // event 객체의 target속성을 통해 접근하는 경우 가장 구체적으로 클릭된 element 객체를 가지고 오게된다. // 이때는 전파와 상관없이 클릭된 객체를 가리키게 된다. // 하지만, this키워드의 경우 event가 발생된 영역에 있는 element를 가리키게 되는데 // 지금의 경우는 button을 클릭해도 그 버튼은 fieldset 이벤트 영역에 있고 이는 또 body, html 영역에 있기 때문에 // 해당 이벤트가 발생하면서 속해 있는 영역 element를 가리키게 된다.(전파된 영역의 객체) // 따라서, 캡처링이기 때문에 html->body->field->button순으로 나오게 된다. // 이에 반해, event.target.nodeName의 경우는 button을 클릭시 button, fieldset을 클릭시 fieldset이 나오게 된다. console.log(event.target.nodeName, this .nodeName, phases[event.eventPhase-1]); } document.getElementById( 'target' ).addEventListener( 'click' , handler, true ); document.querySelector( 'fieldset' ).addEventListener( 'click' , handler, true ); document.querySelector( 'body' ).addEventListener( 'click' , handler, true ); document.querySelector( 'html' ).addEventListener( 'click' , handler, true ); </script> <script type= "text/javascript" > /* [ 이벤트의 전파 ] : 위의 코드를 보면 input 태그로 만든 button은 fieldset에 속해 있고, filedset은 body태그에 속해있다. 또, body태그는 html태그에 속해있는데 button, fieldset, body, html 모두에 이벤트 리스너를 등록해 놓고 제일 안에 있는 button을 클릭하게되면, button이벤트만 동작하는 것이 아니라 이벤트가 전파되어 fieldset, body, html 모두 이벤트가 발생하게 된다. 이를 이벤트의 전파라고 하는데 [ 이벤트 전파의 종류 ] 에는 2가지가 있다. button을 클릭시 1. Capturing(캡처링) : button -> fieldset -> body -> html 순으로 이벤트가 수행되는 전파 2. Bubbling(버블링) : html -> body -> fieldset -> button 순으로 이벤트가 수행되는 전파 -> 하지만, 캡처링은 IE의 낮은 버전에서는 지원하지 않는 경우가 많아 선호되지 않고 주로 버블링이 선호된다. 이때, element.addEventListener(첫번째,두번째,세번째) 에서 세번째 인자는 캡처링 유무를 나타내게 되는데 캡처링 방식으로 할 경우 true를 기술해주고, 버블링 방식으로할 때는 생략하거나 false를 입력해 주면 된다. -> element.addEventListener("click",function(){},false) */ /* [ 이벤트 전파의 방지 ] : 이벤트 전파를 막는 메서드는 event객체의 stopPropagation()메서드이다. 예를들어, 전파되던 이벤트를 body에서 더이상 전파되지 않도록 한다면(버블링일 경우) (body element).addEventListener("click",function(event){event.stopPropagation()},false) 를 해주면 된다. */ </script> |
[ 태그의 기본 이벤트를 막는 방법 ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | <!DOCTYPE html> <head> <meta charset= "utf-8" > <title></title> </head> /* [ 기본 이벤트를 막는 방법 ] : 예를들어 a태그는 href에 지정된 주소로 이동하는게 기본이벤트이고, form태그의 submit 버튼은 전송하는 역할처럼 각 태그는 기본적인 이벤트를 가진 것들이 있다. 이러한 기본 이벤트를 막는 방법에 몇가지가 있는데 1. inline 방식의 경우 2. 프로퍼티 방식의 경우 : 3. addEventListener 방식의 경우 : event객체의 preventDefault() 메서드를 수행하면 된다. 단!) IE9버전 이하에서는 동작하지 않음으로 -> event.returnValue = false;로 해주면 된다. */ // 1. Inline 방식 <p> <label>prevent event on</label><input id= "prevent" type= "checkbox" name= "eventprevent" value= "on" /> </p> <p> // 위의 체크박스가 체크된 경우 return false하게 된다. <a href= "http://opentutorials.org" onclick= "if(document.getElementById('prevent').checked) return false;" >opentutorials</a> </p> <p> <form action= "http://opentutorials.org" onsubmit= "if(document.getElementById('prevent').checked) return false;" > <input type= "submit" /> </form> </p> <script type= "text/javascript" > var test = function (event){ return false ; // 기본 동작을 막기 위함 } </script> // 2. 프로퍼티 방식으로 기본 동작을 취소하는 방법 <script> document.querySelector( 'a' ).onclick = function (event){ if (document.getElementById( 'prevent' ).checked) // 체크가 되어 있는 경우에 return false ; // return false 하면 a태그의 기본 동작을 막을 수 있다. }; document.querySelector( 'form' ).onclick = function (event){ if (document.getElementById( 'prevent' ).checked) return false ; }; </script> // 3. addEventListener의 경우 -> event.preventDefault() or event.returnValue = false; <script type= "text/javascript" > var test2 = function (event){ if ( document.getElementById( 'prevent' ).checked) event.preventDefault(); // 기본 동작을 막는다. } document.querySelector( 'a' ).addEventListener( "click" ,test2, false ); document.querySelector( 'form' ).addEventListener( "click" ,test2, false ); </script> |
[ FORM 태그의 대표 이벤트 종류 ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <!DOCTYPE html> <head> <meta charset= "utf-8" > <title></title> </head> <pre> [ FORM 태그 관련 대표 이벤트 ] 1. submit : form에서 submit 버튼을 클릭해 form내부의 데이터가 action으로 지정한 곳으로 전달될 때 발생. 2. click : 클릭했을 때 발생되는 이벤트 3. focus : ELEMENT가 포커스를 얻었을 때(입력가능한 상태) 가 되었을 때 발생하는 이벤트 4. blur : ELEMENT가 포커스를 잃었을 때 발생하는 이벤트 </pre> <!-- EX --> 이름 : <input id= "nameID" type= "text" value= "" /> <input type= "submit" value= "제출" /> </form> <script type= "text/javascript" > var areaElement = document.getElementById( "formID" ); // form태그에 submit 이벤트를 건다. areaElement.addEventListener( "submit" , function (event){ if ( event.target.nameID.value.length < 1 ) { // 클릭된 폼태그의 nameID를 가진 엘리먼트의 입력된 값이 한글자보다 작은 경우 event.preventDefault(); // 기본이벤트를 방지함 -> 즉, submit발생을 막음 // addEventListener의 경우 기본동작을 막기 위해 return false대신 preventDefault()를 사용한다. alert( "이름은 반드시 입력되어야 합니다." ); } }); </script> <script type= "text/javascript" > // focus를 얻었을 경우 이벤트를 발생 var nameElement = document.getElementById( "nameID" ); nameElement.addEventListener( "focus" , function (event){ alert(event.target.id + "가 포커스를 얻었습니다." ); }); // focus를 잃었을 경우 이벤트를 발생 nameElement.addEventListener( "blur" , function (event){ alert(event.target.id + "가 포커스를 잃었습니다." ); }); </script> |
[ 문서의 태그의 로딩과 관련된 load와 unload 이벤트 ]
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <!DOCTYPE html> <head> <meta charset= "utf-8" > <title></title> <script type= "text/javascript" > function unloadF(){ alert( "해제" ); } </script> </head> <pre> [ 문서의 로딩과 관련된 load 이벤트와 unload 이벤트 ] 1. load : html태그가 전부 로딩되어 접근할 수 있는 상태가 되었을 때 발생하는 이벤트이다. 2. unload : html 태그가 메모리에서 내려가기 직전에 호출되는 이벤트이다. -> 현재 창이 닫히기 직전에 특정 작업을 처리 후 닫고자 할 때 사용하면 좋다. load 이벤트가 중요한 이유는, 특정 ELEMENT에 접근하는 스크립트를 load 이벤트 없이 선언할 때에는 접근하려는 ELEMENT보다 아래쪽에 위치시켜야 한다는 것이다. why? 아직 메모리에 올라오지도 않은 상태에서 스크립트가 접근하려하면 존재하지 않는 ELEMENT를 참조하게 되니까 오류가 발생하게 된다. 따라서, 바디태그 맨 밑쪽에 위치하는 것이 좋지만 그렇게 하지 않고도 load 이벤트 발생시(태그가 다 로딩되면) 해당 스크립트가 동작하도록 해줘도 된다. 또한, load와 unload 이벤트는 inline방식으로는 body태그에서 수행해주면 된다. </pre> <script type= "text/javascript" > // 해당 스크립트는 areaID div 보다 위에 위치해 있음으로 본래 오류가 나야하지만 // 나지 않도록 load함수로 수행토록 하겠다. // 프러퍼티 이벤트 방식 window.onload = function (){ document.getElementById( "areaID" ).innerHTML = "데이터 넣기" ; } // 이때, onload 프러퍼티로 이벤트를 지정할시 단점은 무엇일까? // -> 만약 본인이 onload 이벤트를 두번 지정할 경우 더 아래에서 지정한 // onload이벤트로 덮어버려 이전에 선언한 onload는 동작하지 않게 된다. // 따라서, onload 이벤트 지정시 addEventListener를 통해 등록해주도록 하자. window.addEventListener( "load" , function (){ document.getElementById( "areaID" ).style.border = "1px solid red" ; }); </script> <div id= "areaID" ></div> |
[ 그 외 알아두면 좋은 이벤트 ]
- contextmenu event : 마우스 우클릭시 발생
-> 마우스 우클릭 방지 이벤트(요소 검사(F12)를 방지하기 위해 사용 가능)
- shift, ctrl 키와 같이 클릭했는지 유무를 알 수 있는 event 프러퍼티
event.shiftKey, event.ctrlKey
- 클릭한 곳의 마우스 좌표를 알 수 있는 event.clientX, event.clientY
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <!DOCTYPE html> <div id= "target" style= "border:1px solid red; width:100px;height:100px;" ></div> <script type= "text/javascript" > /* 1. [ contextmenu 이벤트 : 마우스 우클릭 관련 이벤트 ] : 해당 속성을 이용해 요소 검사를 못하도록 마우스 우클릭을 막을 수 있다. */ var targetObj = document.getElementById( "target" ); targetObj.addEventListener( "contextmenu" , function (event){ // event.type -> 발생한 이벤트의 종류를 알 수 있다. if ( event.type == "contextmenu" ){ // 이벤트가 contextmenu이면 event.preventDefault(); // 기본동작을 막음(마우스 우클릭 방지) alert( "우클릭 불가능" ); } }); </script> <!-- 2. [ change 이벤트 ] : select 박스, input, textarea 등의 값이 바낄때마다 호출되는 메서드 --> <select id= "sel" > <option value= "JAVA" >JAVA</option> <option value= "CSS" >CSS</option> </select> <script type= "text/javascript" > document.getElementById( "sel" ).addEventListener( "change" , function (event){ alert( "변경된 값 : " + event.target.value); }); </script> <!-- 3. [ 클릭 이벤트시 보조키를 같이 누른지 여부를 체크하는 방법 ] 1) shift키 : event.shiftKey 2) ctrl키 : event.ctrlKey --> <div id= "target2" style= "border:1px solid blue;width:100px;height:100px;" ></div> <script type= "text/javascript" > document.getElementById( "target2" ).addEventListener( "click" , function (event){ if ( event.shiftKey ) { // click시 shift키를 같이 누른 경우 alert( "click + shift key" ); } else if ( event.ctrlKey ) { alert( "click + ctrl key" ); } else { alert( "just click" ); } }); </script> <!-- 4. [ 클릭이벤트가 발생한 마우스 좌표를 구하는 clientX, clientY ] --> <div id= "target3" style= "border:1px solid green;width:100px;height:100px;" ></div> <script type= "text/javascript" > document.getElementById( "target3" ).addEventListener( "click" , function (event){ alert( "클릭 좌표 : ( " + event.clientX + " , " + event.clientY + " )" ); }); </script> |
'스터디 > 자바스크립트 완벽 가이드 정리' 카테고리의 다른 글
Text Node 제어와 Document 및 스크린, 스크롤 위치 제어 (0) | 2017.12.05 |
---|---|
Node 객체에 대하여(NODE 객체와 NODE객체 컨트롤하기) (0) | 2017.12.03 |
5판 7장 객체(Object)와 배열(Array) (0) | 2017.11.13 |