Rev. 2.73

Ajax의 활동여부를 알리기 위한 알림이(Indicator)를 표시하기 위해 똑같은 반복 작업을 한적이 있다. 모든 Ajax요청의 onLoading, onComplete 콜백에 알림이를 보이고 숨기는 코드를 삽입하는 것이다. 목적이 서로다른 Ajax요청이 수십가지에 달한다면 매우 비효율적인 작업이 아닐 수 없다. 그러나 Prototype의 코어를 조금만 손대면 매우쉽게 전역 Ajax알림이를 구현할 수 있는 꼼수가 있다. 아래와 같은 Indicator라는 함수가 있다고 가정하자.

// Global Ajax Indicator
var Indicator = Class.create({
  initialize: function() {
    this.element = document.createElement('div');
    this.element.style.display = 'none';
    this.element.className = 'indicator';
    document.body.appendChild(this.element);
  },
  show: function() {
    this.element.show();
  },
  hide: function() {
    this.element.hide();
  }
});
Indicator = new Indicator();

보통은 아래와 비슷한 형식으로 Ajax 작동상태를 표시한다.

new Ajax.Request('/ajaxUrl', {
  onLoading: function() {
    Indicator.show();
  },
  onComplete: function() {
    Indicator.hide();
  },
  onSuccess: function(req) {
    // some actions
  }
});

Ajax객체를 생성 할 때 마다 위와 같은 작업을 일일이 해야하는 것이다. 그리고 때로는 onComplete 콜백을 놓치는 경우도 있어 알림이가 영영 사라지지 않는 현상도 발생한다. prototype.js의 Ajax.Responders.register 메서드를 아래와 같이 오버라이드하면 이 문제를 일거에 해결 할 수 있다.

// show/hide indicator on all Ajax callbacks
Ajax.Responders.register({
  onCreate: function() {
    Indicator.show();
    Ajax.activeRequestCount++;
  }, onComplete: function() {
    Indicator.hide();
    Ajax.activeRequestCount--;
  }
});

하지만, Ajax요청마다 알림이의 모양과 위치가 다르다면 '즐'이다.

Comments

prototypeonieerror.gif

어느 때 부터인지 IE에서 특정한 페이지를 로드하면 원인을 알수 없는 오류가 지속적으로 나타나는 증상을 보여서 디버깅에 들어갔다. Prototype 1.6.0 release candidate로 업데이트한 후 위 화면과 같은 문법오류 메시지가 나타나는 요상한 증상을 서로 다른 프로젝트에서 경험했다. 처음 접했을 때에는 인코딩에서 발생한 문제로 판단하고 별별 삽질을 강행하다가 울며 겨자먹기로 버전다운 할 수 밖에 없었다. 결국에는 수천 라인을 비교추적하는 작업 끝에 버그발생의 원인을 알아내고 말았다. 이 허무맹랑한 현상은 Dean Edwards씨에 의해 새롭게 생겨난 'contentloaded' 이벤트 때문에 발생한다.

prototype.js의 4013라인에 아래와 같은 문장이 있다.

4013      document.write("<script id=__onDOMContentLoaded defer " +
4014            "src='://javascript:void(0)'><\/script>");

위 문장을 다음과 같이 수정하면 오류가 사라진다.

4013      document.write("<script id=__onDOMContentLoaded defer " +
4014           "src='http://javascript:void(0)'><\/script>");

그러나, 오류만 사라지고 'contentloaded' 이벤트가 발동하지는 않았다. 이 이벤트는 DOM의 드로잉이 완료되는 시점에 발동하는 이벤트이다. 모든 컨텐츠의 로딩이 완료되는 시점에 발사되는 onload와는 차별되는 이벤트다. 이와 같은 문제로 골머리를 앓고 있는 개발자가 여럿 있다는 사실을 구글링을 통해 알 수 있었고 아래와 같은 해결방안을 찾을 수 있었다.

4013      document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>"); // fix syntax error

아..... 요 벌거지 때문에 이틀 밤잠을 설레발쳤다.... 이제 자야지...

Comments

581915.gif

Shaun Inman씨는 깔끔한 파일 타입 인풋을 자바스크립트와 CSS 그리고 DOM을 이용해 만드는 과정을 소개했다. 우선 데모를 확인하기 바란다. 뭔가 허전하지 않은가? 텍스트 영역과 업로드 버튼이 사라지고 없다. "Choose file..."을 클릭하여 파일을 선택하면 자바스크립트에 의해 자동으로 파일의 업로드가 진행되어 조금 더 사용성이 좋은 파일 업로드 환경을 제공할 수 있다.

label 태그의 class에는 "cabinet"을 그리고 input태그의 class에 "file"을 정의했다. 충돌을 막기위해 부모 엘리먼트가 필요하며, 부모 엘리먼트의 class는 "SI-FILES-STYLIZED"로 가정하자.

마크업 하기

<label class="cabinet"> 
    <input type="file" class="file" />
</label>

스타일시트

.SI-FILES-STYLIZED label.cabinet {
    width: 79px;
    height: 22px;
    background: url(btn-choose-file.gif) 0 0 no-repeat;

    display: block;
    overflow: hidden;
    cursor: pointer;
}

.SI-FILES-STYLIZED label.cabinet input.file {
    position: relative;
    height: 100%;
    width: auto;
    opacity: 0;
    -moz-opacity: 0;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}

첫 번째 프로퍼티는 포장될 엘리먼트의 스타일이다. 버튼의 이미지까지 들고 있다. 두번째 프로퍼티는 인풋의 스타일이다. 완전히 투명한 알파값을 지니고 있다. 그리고 정확하게 두 엘리먼트가 포개지는 구성을 가지고 있다는 것을 알 수 있다. 허상으로 나타는 input 버튼이 작동하게 하기 위한 트릭이라는 것을 알 수 있다.

자바스크립트

<script type="text/javascript" src="/path/to/si.files.js"></script>

자바스크립트 파일을 인클루드하고 onload 이벤트에 SI.Files.stylizeAll();를 선언하면 완료된다. IE 5.5+, 파이어폭스 1.5+, 사파리 2+ 에서 작동되며, 라이브러리와 예제는 이곳에서 다운로드 할 수 있다. 딱 한가지 단점이라면 자바스크립트가 작동하지 않는 환경에서는 업로드가 정상적으로 작동하지 않는 것이다.

Comments