현재 개발하고 있는 웹서비스에 믹시처럼 화면 하단으로 내려 갔을 시에 Event를 날려주는 함수를 만들려고 하는데 Ext에는 딱히 마땅한 함수가 없었다. 이를 만드려면 제일 하단에 있는 Element와 현재 viewport의 거리를 계산해야 하는데 마침 prototype Framework에 적절한 함수가 있었다.
뭐 여튼 이 패턴을 이용하여 추가시켜주면 간단하게 원하는 Methods를 Ext.Element에 추가할 수 있다.
Element.Methods = {
viewportOffset: function(forElement) {
var valueT = 0, valueL = 0;
var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
// Safari fix
if (element.offsetParent == document.body && Element.getStyle(element, 'position') == 'absolute')
break;
} while (element = element.offsetParent);
element = forElement;
do {
if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
} while (element = element.parentNode);
return Element._returnOffset(valueL, valueT);
}
}
viewport의 크기를 계산하는 함수도 필요해서 Ext Doc을 뒤져보니 없어보여서 몇 시간 동안 완전 열심히 땅을 파다가, 코드를 뒤져보니 나오더라는...제길 (왜 Doc에는 나와있지 않았을까; 그리고 왜 이 함수는 Ext.lib.Dom에 있는거지;; 확실히 아직 정식 버젼이 아니다 보니 Doc에 빠져있는게 있긴 한 듯 싶다.)
Ext.lib.Dom = {
getViewportHeight: function(){
return Ext.isIE?(Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) : self.innerHeight;
},
getViewportWidth : function() {
return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth : Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;
}
}
Ext의 viewport 크기 구하는 함수
prototype Framework에 있는 함수를 추가 시키려고 했더니 뭔가 좀 이상해서 봤더니만 Ext의 구조가 3.0으로 올라오면서 바뀌었다. 이전 버젼에서는 Ext.Element.prototype에 함수를 추가 시켜줬었는데 3.0 버젼부터는 Ext.Element.addMethods() 메소드를 이용하여 추가 되어있다.
함수 자체는 특별할게 없고, 함수 안에 써주는 내용을 보니 Douglas Crockford가 Global 변수는 죄악이라면서 만든 Module Pattern을 사용하였다. (A Javascript Module Pattern) 이 패턴은 Javascript의 Closure (Closure에 대한 부가 설명)를 적절히 이용한 패턴인데, 이 특성을 이용하여 private와 public을 사용할 수 없었던 Javascript에서 이를 가능케 한다. (뭐 물론 개발할 당시에는 디버깅이 불편하기 때문에 유명한 자바스크립트 개발자 Snook - 왠지 전형적인 개발자처럼 생겼다 - 은 Module Pattern을 사용하지 말자는 이야기도 했다. - why I don't love javascript's module pattern
뭐 여튼 이 패턴을 이용하여 추가시켜주면 간단하게 원하는 Methods를 Ext.Element에 추가할 수 있다.
Ext.Element.addMethods(function(){
return {
viewportOffset: function() {
var valueT = 0, valueL = 0;
var element = this.dom;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
// Safari fix
if (element.offsetParent == document.body &&
Element.getStyle(element, 'position') == 'absolute') break;
} while (element = element.offsetParent);
element = this.dom;
do {
if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
} while (element = element.parentNode);
return Element._returnOffset(valueL, valueT);
}
}
}());
Ext.Element에 추가된 viewportOffset Method
크게 변경된 것은 없고 Ext.Element 내에서 해당 Element의 dom 객체는 prototype Framework와 달리 this.dom이 가지고 있기 때문에 forElement를 this.dom으로 변경해주었다. 그리고 코드 용량을 줄여주기 위해 minify! (douglas Crockford의 The JavaScript Minifier나 웹상에서 간단히 변경시킬 수 있는 Vlead를 쓰면 된다. 이외에도 여러가지 minifier가 있으니 검색의 활성화~)
Ext에 함수 추가하기 참 쉽죠잉~
곁다리) Ext 3.0 정식 버전이 빨리 나왔으면 좋겠다. 군더더기도 많이 없어졌고, 코드도 훨씬 간결해져서 보기도 좋은 듯. 코어 부분을 gzipped하면 js 파일 크기가 25kb라니..우왕굳!

