Rev. 2.73

굵직한 자바스크립트 관련 웹 프로젝트들을 진행하다 보면 개발자간 협업에서 부디치는 문제가 상당수 있습니다. 뜻하지 않게 네임스페이스를 비효율적으로 사용하거나 이벤트가 무작위로 생성되기도 하고 심지어 중복된 결과를 낳는 함수를 각자 개발하는 사례도 있습니다. 특히, window객체에 할당하는 이벤트 처리는 전역에 걸쳐 발동하게 되기 때문에 코드 자체를 작업자간에 공유하여 작업하거나 window.onload와 같은 이벤트를 중복해서 할당해 버리는 경우도 많습니다. 이 문제를 조금 더 효율적으로 처리할 방법을 강구하다가 아래와 같은 이벤트의 재사용 방법을 모색하게 되었습니다.

/**
 * Dynamic event observation
 *
 * @author firejune <to [at] firejune [dot] com>
 * 
 * @usage : 
 *   - Event.addObserve['load'].initializeTooltip = new Tooltip;
 *   - Event.addObserve['resize'].accordionResize = function() { 
 *       Accordion.resize(); 
 *     };
 * 
 * @requires 
 *   - prototype.js <prototypejs.org>
 * 
 */

Event.addObserve = {
  load : {},
  scroll: {},
  resize: {}
};

// Align global event-oservers
for (var evt in Event.addObserve) {
  var eventObj = Event.addObserve[evt];
  var attachFunc = Prototype.emptyFunction;

  if (!eventObj) continue;

  // Call the functions
  var callFunctions = function(bind, obj) {
    var report = [];
    for (var func in obj) {
      if (func && typeof obj[func] == 'function') {
        obj[func](bind);
        report.push(func);
      } else {
        //debug(obj[func], 'is not a function');
      } 
    }
    //debug('called functions: ' + report);
  };

  if (evt == 'load') {
    attachFunc = callFunctions.bindAsEventListener(this, eventObj);
  } else {

    // Better performance for IE
    attachFunc = function() {
      if (typeof Event.oserveTimeOut == "number") {
        window.clearTimeout(Event.oserveTimeOut);
        delete Event.oserveTimeOut;
      }
      Event.oserveTimeOut = setTimeout(function(){
        callFunctions(this, eventObj);
      }.bind(this), 100);
    }.bindAsEventListener(this);
  }

  // Observing Events
  Event.observe(window, evt, attachFunc, false);
}

이로써 window객체로 할당되는 이벤트를 재사용하여 함수를 동적으로 관리할 수게 되었습니다. 그리고 윈도 리사이즈와 스크롤 이벤트에는 성능향상을 위해 100 밀리세컨즈 뒤에 실행되도록 setTimeout이 적용되어 있습니다. 유저의 무리한 컨트롤에 대응하고 쓸대없는 계산을 줄이기 위해서 입니다. 위 코드를 적절한 곳에서 한번만 실행되게 하면 아래처럼 필요한 때에 추가/대체/무력화 할 수 있습니다. 단, 라이브러리(Open source, Open API)와 같은 비의존성 겸손한(Unobtrusive) 자바스크립트 프로그래밍과는 거리가 멀기 때문에 항상 유용한 것은 아니라는 점 참고하시기 바랍니다.

// A개발자의 Tooltip 클래스가 초기화 되기위한 이벤트 핸들러
 // 단, 온로드 이벤트가 발생하기 전에 선언해야 한다. 
 Event.addObserve['load'].initializeTooltip = Tooltip = new Tooltip;

 // B개발자의 Accordion 클래스가 초기화 되기위한 추가 이벤트 핸들러
 Event.addObserve['load'].initializeAccordion = Accordion = new Accordion;

 // B개발자의 Accordion 리사이즈 이벤트 핸들러
 Event.addObserve['resize'].accordionResize = Accordion.resize; 

 // A개발자의 Tooltip 클래스에 필요한 문서크기 재계산 추가 이벤트 핸들러
 Event.addObserve['resize'].tooltipResize = function() { 
   var element = $('element1') || $('element2');
   Tooltip.setDocumentPositions(element); 
 };

 // B개발자가 추가했던 Accordion 리사이즈 이벤트 핸들러 무력화
 Event.addObserve['resize'].accordionResize = null; 

Comments

Got something to add? You can just leave a comment.

Your Reaction Time!

captcha

avatar