현재 개발하고 있는 웹서비스에 믹시처럼 화면 하단으로 내려 갔을 시에 Event를 날려주는 함수를 만들려고 하는데 Ext에는 딱히 마땅한 함수가 없었다. 이를 만드려면 제일 하단에 있는 Element와 현재 viewport의 거리를 계산해야 하는데 마침 prototype Framework에 적절한 함수가 있었다.
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라니..우왕굳!
저작자 표시 비영리 동일 조건 변경 허락
Posted by 코리아몽키
이번에 Flex로 위젯을 만들게 되었는데 서버로부터 xml 데이터를 가져와 이를 뿌려줘야 하는 기능이 필요했다. Javascript에서는 json으로 변환해주는 라이브러리가 많아 간편하게 쓸 수 있는 XML 파서 라이브러리가 있나 찾아봤는데 생각처럼 잘 검색되지 않았다. (뭐 어딘간 있겠지..;;) 뭐 있다 하더라도 받아오는 xml 데이터 형식이 그리 복잡하지도 않고 바뀌지도 않기 때문에 만들어보았다.
 
// create ArrayCollection
var dataArrCol:ArrayCollection = new ArrayCollection;

// xml to ArrayCollection
dataArrCol = xmlToArray(xmlData);		

public function xmlToArrayCol(xml:XML):ArrayCollection{ 
    // variable set
	var item:XML, value:XML, obj:Object;
	var arrCol:ArrayCollection = new ArrayCollection;

    //xml Parsing
	for each(item in xml.children())
	{
		if(item.name() != "item")
		      continue;

		obj = {};	
		for each(value in item.children())
		{
             // get name to using object key from xml  and set data
			obj[value.name()] = value.toString();
		}

		arrCol.addItem(obj); 
	}
 
    // return ArrayCollection;
	return arrCol;
}
만들어본 xml to ArrayCollection 함수


함수 구조는 뭐 크게 어렵지 않다. 다만 범용적으로 만들지 않고, 내가 쓰는 xml을 파싱하는데 맞췄기 때문에 다른데에 사용하려면 수정이 필요하겠지.

	
		131
		1
		comjji
		9
	
	
		132
		3
		comjji
		7
	
	
		133
		2
		comjji
		1
	

	100

XML Data


 현재 들어오는 xml 데이터가 이런 구조이기 때문에 우선 children 중에 item이 아닌 것은 걸러주고 item일 경우에는 item의 property를 object의 key로 설정하여 값을 집어넣는다. 원래는 들어오는데로 차곡차곡 쌓아서 index로 접근하려고 했는데 나중에 소스를 봤을 때 뭐가 뭔지 모를 꺼같기도 하고, 다른 사람이 유지보수를 하게 되면 key값으로 접근하는게 더 쉬어보이므로 이런 방식을 선택했다.

 각 item 별로 object에 넣은 뒤 arraycollection에 addItem! 원래는 array를 이용하려고 했는데 검쉰님의 글(ArrayCollection에 대한 이해) 을 읽어보니 array에서는 동적으로 아이템을 추가, 삭제하려면 splice를 이용해야 된다길래 ArrayCollection을 이용하였다. 게다가 arrayCollection에서는 아이템이 변경되었을 때 이벤트 처리가 가능하다고 하니 좀 더 낫겠지.

곁다리) 내가 검색을 못하는건지 자료가 부족한건지 모르겠지만, XML 파싱하여 그 데이터를 처리하고 이용하는 방법에 대해서 정리된 자료가 없었다. xml 데이터를 많이 가져다 쓸텐데; 왜 없을까.. 다른 분들은 어떻게 구현했는지 궁금하다.
저작자 표시 비영리 동일 조건 변경 허락
Posted by 코리아몽키
웹서핑 하다가 자바스크립트에 대해서 괜찮은 포스팅들이 많이 되어있는 블로그를 찾아서 이 글 저 글 보다가 상당히 마음에 드는 라이브러리를 발견! 라이브러리 소개 사이트의 문구부터 상당히 인상적이다.

say "hello" to Blackbird and "goodbye" to alert()


 일반적으로 javascript를 이용하여 개발할 때에 alert()을 이용하여 변수의 값을 체크하거나, 디버깅 메세지를 호출하곤 하는데 alert이 호출 되면 이게 다른 동작도 다 멈춰버리기 때문에 은근히 거슬리는 면이 많았다. 게다가 한번에 하나씩 밖에 확인할 수 없는 불편함이 있는데 이 라이브러리는 그러한 불편함을 모두 해소해준다. 뭐 나머지 설명은 사이트에 잘 되어있으니.

 사용법도 상당히 간단하고, UI도 깔끔! 참 마음에 들어서 사용해보려고 하는데, 실장님이 Flex 개발 하라고 하신다.;; 다음에 개발할 때 써봐야지.룰루~
저작자 표시 비영리 변경 금지
Posted by 코리아몽키

오픈웹을 지지합니다
노무현 전 대통령 서거 - 삼가 고인의 명복을 빕니다