Prototype Javascript Framework – Event

이번엔 Prototype의 핵심중 하나라 불릴 수 있는 Event에 대해 알아볼까요?

Prototype에서 제공하는 이벤트 관련 메서드들은 각각의 다른 브라우저에 상관없이 모두 잘 작동하는 특징을 가지고 있습니다.

Event 사용 예제 —————————————————————————————————–
Prototype 1.6에 들어 모든 Event 메서드들은 event 오브젝트 자기자신이 바로 호출 가능하도록 개선되었습니다.

예전의 개발 방법
[code]$(‘foo’).observe(‘click’, respondToClick);


function respondToClick(event) {
  var element = Event.element(event);
  element.addClassName(‘active’);
}[/code]
1.6이후의 새로운 개발 방법
[code]$(‘foo’).observe(‘click’, respondToClick);


function respondToClick(event) {
  var element = event.element();
  element.addClassName(‘active’);
}[/code]
모든 Event 클래스 내의 메서드를 호출하면 해당 이벤트객체는 Event.extend를 거쳐 호출되게 됩니다.

Event Methods —————————————————————————————————–

observe : DOM 엘리먼트에 이벤트를 등록합니다.
[code]Event.observe(element, eventName, handler[, useCapture = false])[/code]
observe를 사용하기에 앞서 프로토타입의 이벤트를 사용하기 위해 HTML 이벤트 속성을 사용하거나(예 : <body onload=”return myFunction()”>) 혹은 DOM 레벨0 이벤트 프로퍼티(예 : window.onload = myFunction;)을 이해하고 있을 필요가 있습니다.

observe 메서드는 기존의 핸들러 메서드들을 새로 만든것이 아니고 엘리먼트와 이벤트를 한데 묶어 사용할 수 있는 기능을 추가한 메서드입니다.

이벤트명은 다음의 기본 이벤트 리스트를 참고하시기 바랍니다 : [ DOM 레벨2 이벤트 ]

간단한 예제)
[code]<form id=”signinForm” method=”post” action=”/auth/signin”>

</form>[/code]
다음과 같은 방법으로 Form submission이 일어날때 checkForm이라는 함수를 수행할 수 있습니다.
[code]Event.observe(‘signinForm’, ‘submit’, checkForm);[/code]
이와같은 이벤트 등록은 form엘리먼트가 DOM트리에 정상적으로 만들어졌을때에 가능합니다. DOM이 완성되는 시기를 기달렸다가 이벤트를 등록하는 방법은 다음과 같습니다.
[code]Event.observe(window, ‘load’, function() {
  Event.observe(‘signinForm’, ‘submit’, checkForm);
}); [/code]

이벤트 메서드를 수행할때 this를 유지하는 법
이벤트를 처리하기 위해 메서드를 수행할때 this는 이벤트가 일어난 엘리먼트가 됩니다.

하지만 경우에 따라 이벤트를 수행할 함수이거나 혹은 다른 객체일 필요가 있습니다.

그런 경우에는 다음과 같이 bindAsEventListener를 사용하여 처리할 수 있습니다.

[code]var Checks = {
  generic: function(event) {
    // 이벤트 처리를 위한 처리 부분
  }
};


Event.observe(‘signinForm’, ‘submit’, Checks.generic.bindAsEventListener(Checks));[/code]
이해되시나요? Checks.generic이라는 메서드가 수행되며 this는 Checks객체가 됩니다. 처리에 매우 용이하게 됩니다.

stopObserving : observe로 등록한 이벤트를 제거합니다.
[code]Event.stopObserving(element, eventName, handler[, useCapture = false])[/code]
이 메서드는 observe로 등록한 이벤트를 제거합니다. 이벤트 핸들러가 제거되면 더이상 엘리먼트+이벤트 페어로 작동하던 이벤트는 작동하지 않게 됩니다.

이벤트를 제거할려면 이벤트를 등록했던 방법과 함수명하나 틀리지 않고 동일해야 합니다.

예제)
[code]// 이벤트 등록
Event.observe(‘signinForm’, ‘submit’, checkForm);

// 이벤트 제거
Event.stopObserving(‘signinForm’, ‘submit’, checkForm);[/code]
하지만 다음과 같은 문제점을 만날 수 있습니다.
[code]var obj = {
  …
  fx: function(event) {
    …
  }
};


Event.observe(elt, ‘click’, obj.fx.bindAsEventListener(obj));


// 다음은 잘못된 방법임
Event.stopObserving(elt, ‘click’, obj.fx.bindAsEventListener(obj));
// 작동하지 않음[/code]
stopObserving을 사용하기 위해서는 bindAsEventListener같은 메서드명이 사용되어 observe되면 안됩니다.

이는 괄호 같은것이 없이 정확하게 메서드명만으로만 등록되어야 합니다.

script.aculo.us 같은 경우에는 다음과 같은 방법으로 해결을 하고 있습니다.
[code]var obj = {
  …
  fx: function(event) {
    …
  }
};
obj.bfx = obj.fx.bindAsEventListener(obj);


Event.observe(elt, ‘click’, obj.bfx);


// 다음은 정상적으로 작동함
Event.stopObserving(elt, ‘click’, obj.bfx);[/code]
필요한 전체 명령문을 간단히 바로가기를 만들어 사용하는것을 알 수 있습니다.

element : 이벤트가 발생한 DOM 엘리먼트를 반환합니다.
[code]Event.element(event) -> Element[/code]
1.5.1 이후 버젼부터는 Event.element를 이미 상속받아 반환됩니다.

예제)
[code]Event.observe(document.body, ‘click’, function(event) {
  var element = Event.element(event);
  if (‘P’ == element.tagName)
    element.hide();
});[/code]
1.6 이상에서는 Event.element(event) 대신 event.element() 라고 사용하는것을 권고하고 있습니다.

extend : 이벤트 객체에 Event 관련 메서드들을 상속받아 확장합니다.
[code]Event.extend(event)[/code]
Event.observeElement.observe 메서드를 사용하여 반환되는 모든 이벤트에 자동으로 상속받습니다.

findElement : 이벤트가 발생한 엘리먼트로부터 상위로 올라가며 원하는 태그명의 엘리먼트를 찾습니다.
[code]Event.findElement(event, tagName) -> Element[/code]
만약에 매칭되는 엘리먼트가 존재하지 않는다면 최상위 엘리먼트인 document가 반환됩니다.

예제)
[code]Event.observe(document.body, ‘click’, function(event) {
  var elt = Event.findElement(event, ‘P’);
  if (elt != document)
    $(elt).hide();
});[/code]

isLeftClick : 마우스 왼쪽 버튼이 눌린 이벤트인지를 확인합니다.
[code]Event.isLeftClick(event) -> Boolean[/code]
정확히는 첫번째 버튼이 눌렸는지를 확인합니다. 오른손잡이 유저의 경우에는 왼쪽 버튼이 눌렸는지를 확인하지만 왼손잡이 유저에게 첫번째 버튼은 오른쪽 버튼입니다.

pointerX : 페이지상에서 마우스 이벤트가 발생한 X좌표를 반환합니다.
[code]Event.pointerX(event) -> Number[/code]

pointerY : 페이지상에서 마우스 이벤트가 발생한 Y좌표를 반환합니다.
[code]Event.pointerY(event) -> Number[/code]

stop : 기본 이벤트를 포함하여 이벤트의 수행을 중단 시킵니다.
[code]Event.stop(event)[/code]
거의 HTML에서 발생할 수 있는 이벤트의 99.9%를 중단시킬 수 있습니다.(라고 Prototype에서 말하는군요-_-;) 기본 이벤트인 submit이벤트같은것도 중간에 중단시킬 수 있습니다.

예제)
[code]Event.observe(‘signinForm’, ‘submit’, function(event) {
  var login = $F(‘login’).strip();
  if (” == login) {
    Event.stop(event);
    // 관련 에러 처리
  }
});[/code]