javascript event.target VS event.currentTarget

target vs curruntTarget

<div class="yellow" id="yellow" style="background: #ff0; width: 300px; height: 150px">
    <div class="green" style="background: #0f0; width: 200px; height: 100px"></div>
</div>

<script type="text/javascript">
var divYellow = document.getElementById('yellow');
divYellow.onclick = function(e){
    e = e || window.event;
    var target = e.target || e.srcElement; //ie대응
    var current = e.currentTarget || this; //ie대응
    alert('target: '+target.className + ' currentTarget: ' + current.className);
}
</script>

아래노랑네모에 클릭이벤트를 걸고,

  • 위초록네모 클릭-> target:위초록 curruetTarget:아래노랑
  • 아래노랑네모 클릭-> target:아래노랑 currentTarget:아래노랑

위초록네모를 클릭하면 그걸 감싸고 있는 아래노랑네모에 event가 bubbling되어 이벤트 발생.

e.target: 이벤트가 일어난 곳
e.currentTarget: 실제로 이벤트가 걸려있는 위치

jQuery curruntTarget

$( "p" ).click(function( event ) {
  alert( event.currentTarget === this ); // true
});

jquery의 curruntTarget은 this와 동일하다.

Refer

https://api.jquery.com/event.currentTarget/
http://jsfiddle.net/misteroneill/kmn4A/3/
http://lidaf.tistory.com/38

Advertisements

Event delegation (Javascript, jQuery)

Event Delegation

  • child element각각에 이벤트 핸들러를 달지 않고
  • parent element에 단 뒤 이벤트가 발생한 노드를 필터링해 처리.
<JS>
document.getElementById('myTd').addEventListener( 'click', function() {
   //you code goes here...
}, false );

<HTML>
<table id="myTable">
   <tbody>
      <tr>
         <td id="myTd">1, 1</td>
         <td>1, 2</td>
      </tr> 
      <tr>
         <td>2, 1</td>
         <td>2, 2</td>
      </tr>
   </tbody>
</table>

myTd에 클릭이벤트를 달았는데, 다른 td들에도 달고 싶다면
각자 노가다로 달아줄 수 있겠지만, 이럴 땐 이벤트를 위임하는 방법을 쓴다(Event Delegation).

document.getElementById( 'myTable' ).addEventListener( 'click', function( e ) {
      if( e.target && e.target.nodeName == 'TD' ) {
         //you code goes here...
      }
   }, false );

jQuery Event Delegation

  • 이벤트 위임은 이벤트의 bubble 속성을 사용한 것입니다.
  • A 엘리먼트에 이벤트 핸들러를 등록하고 싶을 때 그 엘리먼트에 바로 붙이지 않고 그보다 상위 엘리먼트에 B에 등록합니다.
  • 이벤트가 A에서 발생했어도 B로 bubble 되어 올라가는데 이때 B에 등록된 핸들러에서 A에서 발생한 것인지 살펴보고 맞으면 이벤트 핸들러를 실행하는 방식이 이벤트 위임입니다.
  • .bind(), .live(), .delegate() 메서드 모두 jQuery 내부적으로는 .on() 메서드를 사용하게 소스코드가 바뀌었습니다.
  • 그래서 jQuery 1.7 이상 버전을 사용하신다면 여러 메서드들 중 하나를 선택하실 필요없이 그냥 .on() 메서드를 사용하시면 됩니다.
// Attach a delegated event handler
$( "#list" ).on( "click", "a", function( event ) {
    event.preventDefault();
    console.log( $( this ).text() );
});

Refer

http://regularmotion.kr/javascript-patterns-event-delegate/
http://hersheyweb.blogspot.kr/2013/04/javascript-event-delegation.html
http://codefactory.kr/2011/12/07/jquery-performance-tips-and-tricks/
http://learn.jquery.com/events/event-delegation/

자바스크립트 & 제이쿼리 (jpub) – 6장 Javascript event

이벤트 종류

웹을 탐색하는 동안 브라우저에서 발생할 수 있는 이벤트

UI Event

사용자가 웹 페이지가 아닌 브라우저의 UI와 상호작용할 때 발생
– load: 페이지가 가지고 있는 모든 요소(이미지, 스크립트 및 광고)가 전부 로드되었을때만 발생. script요소를 html밑에 정의하면, DOM은 스크립트를 실행하기에 앞서 폼 요소를 먼저 로드하므로 이 경우 load이벤트의 발생을 기다릴 필요가 없다.window.addEventListener('load', setup, false);
– unload: 웹 페이지가 언로드될 때 (주로 새로운 페이지를 요청한 경우)
– error: 브라우저가 자바스크립트 오류를 만났거나 요청한 자원이 존재하지 않는 경우
– resize
– scroll: 전체 페이지 뿐만 아니라 특정 요소(스크롤바 가진 textarea)에서도 적용

Keyboard Event

  • input: input/textarea요소 값이 변경될 때
  • keydown: 사용자가 키를 처음 눌렀을 때 (키가 눌린 동안은 계속해서 발생)
  • keypress: 사용자가 눌렀던 키의 문자가 입력되었을 때
  • keyup: 키보드 키 눌렀다 뗄 때. 화면에 문자가 나타난 이후에 발생

이벤트 순서

  1. keydown – 키 누름
  2. keypress – 키 눌렀거나/누르고 있는중이라 페이지에 문자 입력되고있다.
  3. keyup – 키 뗌

Mouse Event

  • click: 마우스 버튼을 눌렀다 뗄 때
  • dblclick
  • mousedown: 마우스 버튼을 누르고 있을 때
  • mouseup: 눌렀던 마우스 버튼을 뗄 때
  • mousemove: 마우스를 움직일 때(터치스크린X)
  • mouseover: 요소 위로 마우스를 움직였을 때(터치스크린X)
  • mouseout: 요소 바깥으로 마우스를 움직였을 때(터치스크린X)

Focus Event

  • focus / focusin: 포커스를 얻었을 때
  • blur / focusout: 포커스를 잃었을 때

Form Event

  • input: 또는요소 값이나 contenteditable특성을 가진 요소 값이 변경되었을 때
  • change: 선택 상자, 체크박스, 라디오 버튼의 상태가 변경되었을 때
  • submit: 사용자가 (버튼이나 키를 이용하여) 폼을 제출할 때 – 사용자가 폼에 입력한 값을 서버로 전달하기에 앞서, 입력한 값이 올바른 것인지 검사할 때 주로 사용됨.
  • reset
  • cut: 사용자가 폼 필드의 콘텐츠를 잘라내기 했을 때
  • copy
  • paste
  • select: 사용자가 폼 필드에서 텍스트를 선택했을 때

요소에 이벤트를 바인딩하는 세 가지 방법

  1. HTML 이벤트 핸들러
    • 그다지 권장하진 않음. 예전 코드에서 종종 사용.
    • <a>
    • HTML 이벤트 핸들러 특성은 저 위 이벤트 이름과 동일하며, 앞에 on을 붙여 사용.
      • a요소는 onclick, onmouseover…, form요소는 onsubmit, input은 onkeypress, onfocus 등등
  2. 전통적인 DOM 이벤트 핸들러
    • 장점: 모든 주요 브라우저에서 지원.
    • 단점: 이벤트별로 단 하나의 함수만 바인딩 가능
function checkUsername(){
    ...
}
var el = document.getElementById('username');
element.onblur = checkUsername;//(함수이름 괄호는 생략)
- (함수를 호출할 때, 함수 이름 뒤에 괄호를 지정하면 JS해석기는 "이 코드를 지금 실행하라"란 의미로 해석.)

3. 이벤트 리스너
– 현재는 이 방법을 제일 많이 사용.
– 하나의 이벤트로 여러 개의 함수를 실행할 수 있다.
– IE8에선 지원 안함. attachEvent로 구현한다.

function checkUsername(){...}
var el = ...;
el.addEventListener('blur', checkUsername, false);  //버블링:false, 캡쳐링:true

//매개변수를 가진 이벤트 핸들러
el2.addEventListener('blur', function(){
    checkUsername(5);   //이벤트핸들러나 리스너를 지정할 때, 함수 이름 다음에 괄호를 사용할 수 없으므로 인수를 전달해야 하는 경우엔 우회 방법이 필요. - 익명함수
}, false);

이벤트 객체

  • 이벤트 객체는 이벤트가 발생할 떄마다 해당 이벤트에 대한 유용한 정보를 제공.
    • 이벤트를 발생시킨 요소
    • keypress 이벤트가 어떤 키에 의해 발생했느지에 대한 정보
    • 사용자가 뷰포트 내의 어떤 요소를 클릭해서 click이벤트가 발생했는지에 대한 정보
  • 이벤트 객체는 이벤트 핸들러나 리스너로 지정된 함수에 전달된다. 전달받기 위한 함수의 매개변수 이름은 보통 e를 사용한다. (일부 개발자들은 error객체 참조할때도 e라 한다. 헷갈 ㄴㄴ)
function checkUsername(e){
    var target = e.target; //이벤트가 발생한 요소를 가져옴.
}
el.addEventListener('blur', checkUsername, false);

function checkUsername2(e, minLength){  //매개변수 가짐
    var target = e.target;
}
el2.addEventListener('blur', function(e){
    checkUsername(e, 5);
}, false);

//IE 5~8 대응하기
function checkUsername3(e, minLength) {
    var el, elMsg;
    if(!e){
        e = window.event;
    }
    el = e.target || e.srcElement;
    elMsg = el.nextSibling;

    if(el.value.length이벤트 핸들러 함수 호출될때 어떤 요소에서 이벤트 발생했는지 알아내는 최고의 방법은 event객체의 target속성 참조하는 방법이다. 근데 this로도 참조 가능.

- `this.value.length` 처럼 받아올 수 있다.
- 근데 함수에 매개변수를 전달하지 않는(그래서 익명 함수에 의해 호출되는 것이 아닌) 경우에만 제대로 동작.

# focus, blur
```javascript
function checkUsername(){
    var username = el.value;
    if(username.length<5){
        elMsg.className = 'warning';
        elMsg.textContent = "이름이 너무 짧습니다.";
    } else {
        elMsg.textContent = "";
    }
}

function tipUsername() {
    elMsg.className = 'tip';
    elMsg.innerHTML = '이름은 다섯 글자 이상이어야 합니다.'
}

//username입력 필드가 포커스를 받거나 잃으면 위의 함수를 호출하도록 한다.
el.addEventListener('focus', tipUsername, false);
el.addEventListener('blur', checkUsername, false);

이벤트가 발생한 지점

  1. 스크린
    • screenX, screenY
    • 모니터 화면 전체를 대상
    • (브라우저가 아닌)화면의 왼쪽 상단 모서리를 기준으로 현재 커서 위치 알려줌
  2. 페이지
    • pageX, pageY
    • 전체 페이지를 기준으로 현재 커서 위치
    • 페이지 최상단은 viewport를 벗어나 있을 수 있기 때문에 커서가 같은 위치에 있다 하더라도 페이지 좌표와 클라이언트 좌표가 다를 수 있다.
  3. 클라이언트
    • clientX, clientY
    • 브라우저 뷰포트 기준으로 커서 위치 알려줌
    • 스크롤 해서 상단 안보이더라도 클라 좌표는 영향 안받음

변형 이벤트

  • DOMNodeInserted: 돔트리에 노드 추가될때. (appendChild(), replaeChild(), insertBefore()메서드를 호출하면 발생한다.)
  • DOMNodeRemoved: 제거될때
  • DOMSubtreeModified: 변경되면
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument

HTML5 이벤트

  • DOMContentLoaded: 돔트리가 형성될때.더 빠르게 로드되는 것처럼 보일 수 있다. 그러나 스크립트 로딩이 완료되기를 기다리지 않아 미처 로딩되지 않은 스크립트에 의해 생성되는 요소들이 DOM트리에 반영되지 않을 수 있다(window나 document객체 통해 처리)
  • hashchange: URL의 해시가 변경될 때(전체 창이 새로 고쳐지는 것이 아니라)발생. ajax이용해 콘텐츠 로드하는 경우에도 사용.
  • beforeunload: window객체에서 발생. 페이지가 언로드 되기 전에 발생.(ex. 사용자가 폼 데이터를 변경한 상태에서 저장 않고 다른 페이지로 이동하려는 경우에 알림)