레이블이 Prototype인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Prototype인 게시물을 표시합니다. 모든 게시물 표시

2007년 11월 22일 목요일

JavaScript의 객체지향

JavaScript는 단순한 스크립트이지만 객체지향을 지원하고 있습니다.

가령 ClassA와 ClassB가 존재하고 ClassB가 ClassA를 상속하고 있다면 실제 JS로 어떻게 구현할가요?
아래에 그럼 간단한 샘플 코드를 첨부하도록 하겠습니다.

<script>
function ClassA()
{
    this.a='a';
}
function ClassB()
{
    this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
for(var p in objB)document.write(p+"<br>");
</script>

하지만 JS의 원형 상속구조는 Clone(복사) 상속구조가 아닌 Refer(참조)상속입니다.
이런 이유땜에 만약 ClassA인스턴스 맴버변수를 변경하면 ClassB 인스턴스도 변화를 가져오게 됩니다.

<script>
function ClassA()
{
    this.a='a';
}
function ClassB()
{
    this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
alert(objB.a);
ClassB.prototype.a='changed!!';
alert(objB.a);
</script>

하지만 파생된 클래스에서 맴버변수에 대한 수정은 부모 클래스에는 영향을 주지 않으므로 실제 상속된것과 같은 형태로 표현이 되여집니다. 즉 쓰기 작업은 파생된 클래스에 한해서 진행이 되고 읽기는 부모 클래스( 자식 클래스에서 오버라이딩하지 않았을시)에 한해서 진행이 되여집니다.

또한 파생된 클래스 인스턴스가 하나가 아닌 두개가 존재한다면 두 인스턴스가 동일한 부모 클래스 맴버변수를 참조하게 되므로 실제 비교를 해보면 똑같은 결과가 나옴을 알수 있습니다.

<script>
function ClassA()
{
    this.a=function(){alert();};
}
function ClassB()
{
    this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
alert(objB1.a==objB2.a);
alert(objB1.b==objB2.b);
</script>

아래에 첨부한 코드를 살펴보면 가장 치명적인 문제를 발견할 수 있는데, 보시다 싶이 ClassB의 인스턴스 objB1속의 맴버변수의 값만 변경하였을 뿐인데 objB2의 값까지도 변경이 되여져 있습니다.

<script>
function ClassA()
{
    this.a=[];
}
function ClassB()
{
    this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
objB1.a.push(1,2,3);
alert(objB2.a);
// 모든 ClassB 인스턴스속의 a값이 모두 변화가 일어났다!!!
</script>

이러한 원인 때문에 위에서 설명드린 방식으로 상속을 구현하는것 보다는 prototype을 이용하여 상속을 구현하면 실제 저희가 원하는 결과를 얻을수 있습니다.

prototype상속은 파생된 클래스의 원형(原型)객체를 부모클래스의 한 인스턴스로 설정하여 상속을 구현하고 있습니다.

사용상 편이를 위하여 Function 객체의 한 메소드로 정의하여 사용합니다.

Function.prototype.Extends = function (parentClass)
{
  var Bs = new Function();
  Bs.prototype = parentClass.prototype;
  this.prototype = new Bs();
  this.prototype.Super = parentClass;
  this.prototype.constructor = this;
}

2007/11/17 - [분류 전체보기] - Prototype 1.5.0 API
2007/11/14 - [자바 어플리케이션/기타 프레임웍들] - JSValidate - Form Validation Library
2007/09/14 - [자바 어플리케이션/기타 프레임웍들] - Prototype 은 어떻게 DOM에 대한 확장을 하였는가?
2007/09/13 - [자바 어플리케이션/기타 프레임웍들] - prototype 1.5.1.1 Javascript 프레임웍 사용기 - 제1부
2007/02/26 - [자바 어플리케이션/기타 프레임웍들] - Prototype을 위한 퀵 가이드

2007년 11월 14일 수요일

JSValidate - Form Validation Library

JSValidate는 Prototype과 Script.aculo.us을 기반으로 한 심플한 라이버리이며 사용자들로 하여금 폼 유효성체크를 쉽게 할수 있도록 도와줍니다.

라이브러리는 http://www.jsvalidate.com/ 에서 다운로드 받으실수 있습니다.

실제 사용자는 특정된 CSS 클래스를 만들고 이에 관련되여 Form속의 필드에 Annotate를 추가하는것으로만 놀라운 Validation 효과를 만들수가 있습니다.

폼에 사용되여질수 있는 Annotate들은 다음과 같습니다.

  • jsrequired - 필드가 일렬의 값을 필요로 할때(필수입력사항).
  • jsvalidate_number - 모든 인티져 (정수 + 부수)
  • jsvalidate_digits - 오로지 숫자만 허용
  • jsvalidate_alpha - 오로지 알파벳만 허용
  • jsvalidate_alphanum - 알파벳, 숫자만 허용
  • jsvalidate_email - 유효한 메일 주소
  • jsvalidate_uscanzip - 미국과 캐나다의 우편번호만 허용
  • jsvalidate_usstate - 미국 주 이니셜
  • jsvalidate_usphone - 미국 전화번호
  • jsvalidate_creditcard - Validates VISA, MasterCard, American Express 을 허용
  • jsvalidate_ssn - 샘플 포맷으로 열거한 포맷만 허용 - XXXXXXXXX, XXX XX XXXX, or XXX-XX-XXXXX
  • select-notfirst - 콤보박스에서 첫 항목에 대한 선택을 허용않함
2007/11/13 - [분류 전체보기] - Javascript Utility Version 2
2007/02/26 - [자바 어플리케이션/기타 프레임웍들] - Prototype을 위한 퀵 가이드

2007년 9월 14일 금요일

prototype 1.5.1.1 Javascript 프레임웍 사용기 - 제1부

복잡한 JavaScript는 이제 가라!!! 

사용자 삽입 이미지

Prototype LOGO

Prototype 프레임웍은 Samstephenson이 제작한 Javascript 프레임웍이다. 그 목적은 Web 2.0으로 가면서 복잡하게 엉킨 Javascript를 간소화시키기 위함이다. Prototype은 스크립트 기반의 언어의 제한을 뛰여넘어 일반 컴파일 언어 (예하면, C++, Java와 같은) 수준에서 지원하고 있는 상속 및 추상클래스까지도 구현가능하게끔 하였다.
prototype.js는 현재 웹어플리케이션 프로토타입 개발용으로 많은 관심을 받고있는 프레임워크인 RubyOnRails에 통합되어 있으며, script.aculo.us, Rico 등과 같은 다양한 자바스크립트 프레임워크에서도 라이브러리 형태로 사용되어지고 있다.
예제와 참조문서를 읽었을때, Ruby프로그래밍 언어에 친숙한 개발자는 Ruby의 내장 클래스와 이 라이브러리에 의해 구현된 많은 확장 사이의 의도적인 유사성을 알아차리게 될것이다.
그럼 아래에 prototype 을 좀 더 쉽게 사용할 수 있게 끔 가이드(?) 하기 위하여 그에 대한 간단한 설명을 첨부할가 한다.

1. 기초 유틸리티

1.1. Prototype 객체

속성 및 방법
Version : 문자열은 prototype 프레임웍의 버전을 명시해준다.
ScriptFragment : 스크립트의 정규모드 유효성 체크를 해준다.
emptyFunction(): 빈 함수를 나타낸다. Function() {}
K(x): K메소드, 파라미터 자신을 리턴한다.
1.5부터는 JSON을 지원하면서 기능이 막강해졌다.

소스 열기

1.2. Class 객체

Class객체는 오로지 하나의 작용밖에 없다. 그건 바로 클래스정의에 대한 지원이다.

소스 열기

가장 보편적으로 사용하는 방식을 예로 들면 다음과 같다.

예제 열기

윗 예제를 보면 Animal이라는 클래스를 Class.create라는 메소드를 통하여 생성한다.
다음 initialize 생성자를 만들고 name, sound를 인자로 입력를 받는다.
밑에 보면 Dog라는 클래스도 생성해 주고 있는데 실제상 이 Dog클래스는 Animal 클래스를 상속받고 있는다.
Dog.prototype = Object.extend(new Animal(), 단순히 extend 메소드를 통하여 상위클래스를 쉽게 상속받을수가 있다.

1.3. Object 클래스에 대한 확장

Object는 모든 객체의 기초로 되는 클래스이다. 즉 모든 객체는 Object클래스를 상속받아서 구현이 되여진다. 1.5버젼으로 업그레드 되면서 Prototype은 Object클래스에 4개의 static 메소드를 추가했다.
static 메소드 그 첫번째:
syntax => Object.extend(destination, source)
설명 => source 파라미터의 모든 속성을 destination에 넘겨준다. 이렇게 함으로써 destination이 source상속 받은것과 같은 효과를 나타낸다.
static 메소드 그 두번째:
syntax => Object.inspect(object)
설명 => 파라미터로 지정된 오브젝트로 자신의 inspect메소드를 구현해야 한다.
static 메소드 그 세번째:
syntax => Object.clone(object)
설명=> 원 오브젝트의 모든 속성을 그대로 복사하여 새 오브젝트에 넣어둔다. 하지만 이런 복사는 deep복사인거 아니라 shallow복사이다.
Syntax => Object.keys(object)
설명=> 모든 오브젝트를 hash로 간주하여 처리하며 결과적으로 이런 속성들의 이름을 리턴한다. 하지만 추가된 요소들의 정열순서는 보장할수 없다. 사용자가 만약 각 요소가 정열이 되여질것을 원하면 자기 스스로 이부분의 코딩을 해야 한다.
Syntax => Object.value(object)
설명=> 모든 오브젝트를 hash로 간주하여 처리하며 결과적으로 이런 속성들의 값을 리턴한다.
Syntax => toJSON()
설명 => JSON 문자열을 리턴한다.

소스 열기

Clone예제 열기

Key예제 열기

Value예제 열기

1.4 Number 클래스 확장
Number은 모든 숫치유형의 기본 클래스이며 prototype에서는 그 인스턴스에 대하여 확장을 진행하였다.
syntax => toColorPart()
설명 => RGB색상을 16진법 색상 표시법으로 변환한다.
예 => var cRed=255, cGreen=100, cBlue=22;
var hexColor="#"+cRed.toColorPart() + cGreen.toColorPart() + cBlue.toColorPart();
syntax => succ()
설명 => 숫치에 1을 합하여 리턴한다.
syntax => times(iterator)
설명=> 여기서 iterator은 함수이며 iterator라는 함수를 여러번 수행하고 싶으로 이 메소드를 사용한다.

소스 열기

1.5 Try 객체
이 객체는 오로지 하나의 메소드만 제공해준다. these메소드 사용시 넘겨받은 인수는 메소드 핸들러 여야만 한다. 그 작용은 맨 처음 성공적으로 실행된 메소드의 반환치를 리턴하는것이다.

소스 열기

2 기초 도구류
이부분에서는 prototype 1.4.0 프레임웍의 일부 핵심 툴들을 정의하고 있으며 전체 프레임웍의 중요한 구성 부분이다.

2.1 $() 함수
$() 함수는 매우 빈번하게 사용되는 DOM의 document.getElementById() 함수에 대한 편리한 단축함수이다. DOM 함수처럼, 이것은 인자로 던져진 id를 가진 해당 엘리먼트를 반환한다. 하지만 DOM함수와는 달리, 이것은 여러개의 id를 사용할수 있는데, 이 경우에 $()는 요청된 엘리먼트들을 가진 Array 객체를 반환하게 된다. 이 함수의 다른 장점으로 id 문자열이나 엘리먼트객체 자체를 인자로 가질 수 있는데, 이것은 인자 형태를 가질수 있는 다른 함수를 생성할 때 매우 유용하게 사용되어 질 수 있다.

소스 열기

예제 열기

2.2 $F() 함수
$F() 함수는 또다른 유용한 단축함수로, 텍스트박스나 드랍다운 리스트와 같은 입력 컨트롤의 값을 반환한다. 이 함수는 엘리먼트 id나 엘리먼트객체 자체를 인자로 가질수 있다.

소스 열기

예제 열기

2.3 $A() 함수
$A() 함수는 전달된 한 개의 인자를 배열로 변환한다. Array 클래스에 대한 확장으로 이 함수는 열거가능한 목록이라면 그것을 쉽게 배열로 변환할 수 있더. 예를 들면, DOM 객체의 NodeLists를 효과적으로 배열로 바꾸는데 유용하게 쓰일 수 있다.

소스 열기

예제 열기

2.4 $R() 함수
$R() 함수는 new ObjectRange(lowerBound, upperBound, excludeBounds)과 동일한 단축함수이다. 아래는 each 메소드를 통해 반복(iterators)의 사용법을 보여주는 간단한 예제이다.

소스 열기

예제 열기

2.5 String 클래스에 대한 확장

Javascript에서 모든 문자열은 모두 String 클래스의 인스턴스들인바 이런 인스턴스들에 대한 오버레이션을 간편화하기 위하여 몇가지 메소드들을 제공하였다.

2.5.1 stripTags 메소드
태그를 없애는메소드로서 이정규 표현이라면 올바르게 태그를 없앨 수 없는 경우가 있다.

소스 열기

2.5.2 stripScripts 메소드
캐릭터 라인(this)으로부터,script블록을 삭제하는 메소드이다. 전술 Prototype오브젝트의ScriptFragment 프롭퍼티로부터 script 블록의 정규 표현 캐릭터 라인을 취득하고 있다.

소스 열기

2.5.3 extractScripts 메소드
캐릭터 라인(this)의 모든 script 블록의 내용을, 배열에 격납해 반환하는 메소드이다.
Prototype.ScriptFragment를 사용해, 글로벌 매치하는 정규 표현 오브젝트와 싱글 매치하는 정규 표현 오브젝트를 작성한다. m수식자는 무의미한 생각이 든다.
캐릭터 라인(this)으로부터 모든 script 블록을 추출해, 더욱 각각으로부터 script 블록의 내용(코드 부분)을 추출해 배열에 격납해, 반환하고 있다.
인수로 지정된 함수를, 배열 요소 모든 것을 차례로 인수로 지정해 실행해, 결과를 배열에 격납해 반환한다.

소스 열기

2.5.4 evalScripts 메소드
캐릭터 라인(this)으로부터, extractScripts 메서드로 취득한 script코드 모든 것을, eval함수로 실행하고 있다.
요소의 innerHTML 프롭퍼티에 소스를 설정하면(자), 태그등이 eval되여 실행이 되여지겠지만 script 블록은 실행되지 않는다. 이때 이런 소스를 실행시키는데 evalScripts 메서드가 도움이 된다.

소스 열기

2.5.5 escapeHTML 메소드
캐릭터 라인(this)의 HTML문 자를 이스케이프 해 반환한다. 즉 「text」(이)라고 하는 캐릭터 라인을 「<p>text</p>」로 변환한다.
예하면 "<"를 "&lt;"로 변환한다.

소스 열기

2.5.6 unescapeHTML 메소드
escapeHTML 메서드의 역.캐릭터 라인(this)의 태그를 없앤 다음, 안 이스케이프 해 반환한다.
예하면 "&lt;"를 "<"로 변환해준다.

소스 열기

2.5.7 toQueryParams 메소드
우선, 캐릭터 라인(this)을 쿠에리 캐릭터 라인으로 간주해, 선두 「?」보다 이후의 캐릭터 라인을 「&」으로 분할해 배열에 격납한다. inject 메서드는 Array 클래스의 추가 메서드이다. 제2인수의함수의 제2 인수(pairString)에 배열의 각 요소의 값이 들어온다.처리의 결과를 제일 인수(params)에 격납해 반환한다.이것을 반복해, 최종적인 결과를 격납한 것(params)를 반환합니다.inject의 제일 인수(은)는 반환치의 초기치이다.
즉 여기에서는, 배열의 각 요소의 「name=value」의name를 인덱스,value를 값으로 한 커스텀오브젝트가 반환되게 된다.
예를 들자면
var s = "sid=10&page=2&author=nate";
var qp = s.toQueryParams();
qp의 구조는
{sid:10,page:2,author:'nate'}
가 되여지겠다.

소스 열기

2.5.8 toArray 메소드
캐릭터 라인(this)을, split로 1 문자씩 배열에 격납해 반환한다. 단락 캐릭터 라인에 공문자열을 지정하는 것으로 1 문자씩에 분할한다.
예를 들면
var t = "abc";
var s = t.toArray();
결론적으로 s에 ['a','b','c']이라는 배열로 만들어 진다.

소스 열기

2.5.9 camelize 메소드
캐릭터 라인(this)이 「aaa-bbb」형식일 때, 「aaaBbb」형식으로 변환해 반환한다.CSS프롭퍼티를 오브젝트 모델 구문으로 변환하는 경우에 편리하다. 실제, 후술 하는 Element 오브젝트의 getStyle 메서드로 사용되고 있다.

소스 열기

2.5.10 capitalize 메소드
문자열중 맨 처음 캐릭터만 대문자로 표시하고 나머지는 모두 소문자로 변환시켜준다.
예하면 기입된 문자열이 "yust"라면 capitalize를 거치면 "Yust"로 된다.

소스 열기

2.5.11 startsWith 메소드
문자열 첫 시작부분에 특정된 문자패턴이 있는지를 체크하여 있으면 true을 반환하고 아니면 false를 반환한다.
var str = "CIM campus integrity movement";
str.startsWith('CIM');
이럴경우 true를 반환하게 된다.

소스 열기

2.5.12 endsWith 메소드
문자열 마지막부분에 특정된 문자패턴이 있는지를 체크하여 있으면 true을 반환하고 아니면 false를 반환하다.
var str = "CIM campus integrity movement";
str.endsWith('ment');
이럴경우 true를 반환하게 된다.

소스 열기

2.5.13 dasherize 메소드
문자열중 "_"를 일괄적으로 "-"로 바꿔준다.
예하면
'border_bottom_width'.dasherize();
// -> 'border-bottom-width'

소스 열기

2.5.14 blank 메소드
문자열이 공백이거나 공백만 있을경우 true를 반환한다.
''.blank();
//-> true
' '.blank();
//-> true
' a '.blank();
//-> false

소스 열기

2.5.15 empty 메소드
문자열이 공백이면 true를 반환한다.
''.empty();
//-> true
' '.empty();
//-> false

소스 열기

본 포스트는 계속 업뎃이 되여집니다...

Prototype 은 어떻게 DOM에 대한 확장을 하였는가?

이제 복잡한 DOM코딩은 가라! Prototype만으로 이를 해결한다!

사용자 삽입 이미지
사실상 Prototype에서 가장 주목을 끄는것은 그것이 DOM에 대한 확장성 이다. Prototype은 여러가지 간편한 메소드 (예하면 $()과 같은) 사용자한테 제공하여 DOM에 대한 코딩을 단순화 시켰다.
간단한 예를 들자면 사용자는 단순히 $('comments').addClassName('active').show() 와 같은 코드를 통하여 쉽게 id가 comments인 요소에 active스타일 시트를 추가하고 보여지게끔 한다.(당연 그전에는 hidden상태였겠지)
그렇다면 prototype은 어떻게 이런 쉬운 코딩만으로 DOM에 대한 접근을 가능하게 했을가?

Element.extend() 메소드

거의 대부분의 DOM 메소드들은 Element.Methods 라는 메소드에 의하여 캡슐화 되여지고 이런 엘리먼트 객체로 복사가 되여져 사용이 되여진다.

Element.hide('comments');
var div_height = Element.getHeight(my_div);
Element.addClassName(
'contactform', 'pending');


윗소스를 보면 comment 엘리먼트를 DOM에서 획득해오고 그에대하여 CSS스타일을 적용하는 것이다.
사실 윗소스도 상당히 간편하지만 prototype의 매력은 이뿐만이 아니다.
아래에 다른 예를 하나 더 추가하겠다.

var my_div = document.createElement('div');

Element.extend(my_div);
my_div.addClassName(
'pending').hide();

// insert it in the document
document.body.appendChild(my_div);


소스를 간단히 분석해보면 my_div라는 엘리먼트를 만든다.
다음 Element.extend 메소드에 해당 엘리먼트를 인자로 넘겨주면 Element.extend의 모든 메소드들이 해당 객체에 복사되여져 온다. 이로써 우리는 별도로 메소드 구현이 필요 없이 이미 구현이 되여진 메소드를 그냥 가져다 쓸수 있다.
하지만 실제 구현시 구지 이런 방식으로 엘리머트들에 메소드들을 복사 할 필요가 없다. 단지 $() 를 사용하여서 위와 같은 메커니즘으로 이 모든것을 구현할수 있다.

가령 contactform있다고 가정할 때 이 폼속의 모든 필드 값들을 QueriedString으로 만들어서 넘기고 싶으면 단지 아래 방식처럼 코딩하면 된다.

var contact_data = $('contactform').serialize();


$()를 통하여 contactform은 Element.extend의 모든 메소드들을 상속을 받게 되는데 여기서 serialize가 바로 그중에 한 메소드이다. 이 메소드의 작용은 예전에 포스트내용을 참조하게 쉽게 알수 있는데 바로 폼내의 모든 엘리먼트를 쿼리드스트링으로 만드는 작용을 한다.

Element.addMethods()를 이용하여 사용자 메소드를 추가할수 있다.

Prototype에서 제공해주는 메소드만 사용하여 일부 문제는 해결할수 있을지 모르지만 모든 문제는 해결할수 없다. 즉 사용자 정의 메소드를 추가하고 싶어질거다. prototype은 이런점까지 고려하여 메소드 추가확장기능을 지원한다.

var MyUtils = {
    truncate:
function(element, length){
        element = $(element);
       
return element.update(element.innerHTML.truncate(length));
    },
    updateAndMark:
function(element, html){
       
return $(element).update(html).addClassName('updated');
    }
}

Element.addMethods(MyUtils);

// now you can:
$('explanation').truncate(100);


MyUtils는 사용자 정의 클래스로서 사용자 정의 메소드들을 포함하고 있다. truncate와 updateAndMark 두메소드는 사용자 정의 메소드들로써 Element.addMethods를 통하여 prototype의 Element 클래스에 추가되여 질수 있다.

2007년 2월 26일 월요일

Prototype을 위한 퀵 가이드


소개

웹 도처에 사용되는 자바스크립트의 늘어가는 인기는 클라이언트측 코드가 안정성, 속도, 재사용성등이 혼합으로 구현되도록 하는것이 좀더 중요하게 되었다. 이것을 달성하기 위한 가장 좋은 방법중 하나는 간단한 라이브러리와 모든 프로젝트를 위한 기본사항처럼 사용하기 위한 문법이다. 고맙게도 Sam Stephenson 는 우리의 자바스크립트 개발을 쉽게 하기 위한 Prototype.js 라 불리는 놀라운 함수들의 라이브러리를 만들었다.
우리의 독자들이Prototype 문법을 사용하는 문서 를 읽은 후 크게 놀랐고, 우리는 많은 개발자를 위해 좀더 쉽게 배울수 있도록 도와주는 라이브러리를 위한 참조문서를 만드는게 좋겠다는 결심을 했다. 다음의 튜토리얼은 Particletree프로젝트에서 사용된 가장 공통적인 함수들을 사용하는 간단한 예제와 함께 설명할 것이다. 이 문서는 Sergio Pereira에 의해 좀더 많은 내용을 가진 비공식적인 프로토타입 문서 와 함께 사용되었음을 의미한다. 그리고 script.aculo.us 문서 위키는 모든 자바스크립트/프로토타입 개발자들이 읽기를 매우 추천한다.

시작하기

파일을 다운로드 한 후에, 당신이 선호하는 디렉토리에 그 파일들을 넣어둬라. 당신이 해야할 일은 html문서에 다음처럼 추가를 하는 것이다.

<script src="/scripts/prototype.js" type="text/javascript"></script>

이것으로 자바 스크립트를 개발하는게 10배는 쉬워진다. 지금, 당신이 획득한 새롭고 멋진 무기를 보자.

$() 함수

가장 자주 사용되고 편리한 함수인, $()는 DOM요소를 다루기 위한 쉬운 방법을 제공한다. 일반적으로, 당신이 DOM내 특정 요소에 접근하고자 한다면, 다음처럼 작성할것이다.

node = document.getElementById("elementID");

$()를 사용하면, 다음처럼 간단히 작성할수 있다.

node = $("elementID");

간단하고 멋지지만 이러한 장점보다, $()함수는 다중 요소를 함수안으로 가져오는 기능을 가지고 있기 때문에 document.getElementById()보다 좀더 강력하다.

allNodes = $("firstDiv", "secondDiv");
for(i = 0; i < allNodes.length; i++) {
    alert(allNodes[i].innerHTML);
}

이 예제에서, 우리는 루프를 통해 간단히 접근할수 있는 요소들의 배열을 가지고 오는 것을 볼수 있다.

폼 헬퍼(Form Helper) 함수

폼은 HTML과 CSS관점에서 근심거리일뿐 아니라, 자바스크립트의 측면에서도 그렇다. Prototype.js는 폼을 다루는 유용하고 독창적인 함수를 제공한다.

$F() 함수 는 폼 요소의 값과 전달하는 ID를 반환한다. 만약 우리가 다음처럼 HTML필드를 둔다면,

<input type="text" id="textfield" name="textfield" />
<textarea rows="5" cols="5" id="areafield" name="areafield"></textarea>
<select id="selectfield" name="selectfield">
    <option value="1" selected>One</option>
    <option value="2">Two</option>
</select>
<input type="checkbox" id="checkfield" name="checkfield" value="1" checked />

우리는 $F()함수를 사용하여 폼내의 값들에 쉽게 접근할수 있다.

$F("textfield");      // returns the value of the text input
$F("areafield");      // returns the value of the textarea
$F("selectfield");    // returns the selected value of the select
$F("checkfield");     // returns undefined if not checked, or the value

제어와는 관계없이 값을 얻는 기능은 대부분의 환경에서 좀더 쉽게 폼을 처리하도록 해준다. 여기에 이 함수를 사용할때 찾을수 있는 두가지 결점이 있다. 1) radio그룹의 선택된 값에 접근하는 쉬운 방법이 없다(하나의 radio요소의 값만 처리). 2) $()함수를 사용할때처럼 다중 ID를 전달하는 것이 불가능하다.

*다른 함수인, Form.getElements() 는 타입에 관계없이 모든 폼 요소의 배열을 반환한다.

allNodes = Form.getElements("myform");
for(i = 0; i < allNodes.length; i++) {
    //do something to each form field
}

이 예제에서, 우리는 myform이라는 id를 가진 폼으로 부터 모든 요소를 가져온다. 만약 당신이 onclick을 추가하고 싶거나 각각의 폼필드에 도움말 팝업을 추가하기를 원한다면, 당신은 위와 같은 형식을 통해 할수 있다.

우리가 볼 다음 메소드는 Form.serialize()이다. Ajax요청을 빌드할때, 당신은 데이터를 전달하기 위해 당신 자신만의 문자열을 포맷팅하기를 원한다. 폼이 서브밋되었을때, 문자열은 빌드되고, serialize()는 처리를 쉽게 만든다.

allNodes = Form.serialize("myform");

// returns field1=value1&field2=value2&field3=value3 and so on...

우리를 돕기 위해 문자열을 빌드하라. 하지만 메소드를 좀더 좋게 만드는 것은 이것은 필드의 타입에 기초를 두지 않는 것이다. 우리는 이전에 $F()가 radio그룹에서 몇가지 문제점을 가지는 것을 봤다. 하지만 serialize()는 어떠한 필드 타입을 위해서도 값을 정확하게 처리한다. 사용가능한 폼 메소드만 있는 것은 아니다, 나머지것들을 보기 위해서는 Sergio의 문서 를 보라.

getElementsByClassName

getElementsByClassName()가 아직도 자바스크립트로 빌드되지 않은 이유는 뭔가.? 이것은 프로토타입이 아니고 그래서 프로토타입은 문서객체의 확장처럼 저장소(arsenal)로 이것을 추가했다. 이것은 document.getElementsByTagName()처럼 정확하게 작동한다. 단지 차이점은 className을 체크하는 것이다.

allNodes = document.getElementsByClassName("red");
for(i = 0; i < allNodes.length; i++) {
    alert(allNodes[i].innerHTML);
}

반환되는 배열은 주어진 className과 일치하는 모든 요소를 포함한다. 이것은 다중 className을 가진 요소들과도 잘 작동한다. getElementsByClassName()는 도처에서 모든 프로젝트에서 사용되는 함수가 되었다. 주로 DOM이벤트에 붙기 때문에 나는 모든 개발자가 이것을 사용하도록 제안한다.

요소 헬퍼(Element Helper) 함수

요소객체는 공통적으로 DOM조작을 돕는 많은 수의 헬퍼 함수를 제공한다. 몇몇 이러한 함수는 하나의 호출에 10줄 이상의 코드를 단순화하는동안 어떤 새로운 것도 생성하지 않는다. 그럼 몇몇 예제를 보자.

헬퍼 없이 요소의 높이를 가져오자.

$("first").offsetHeight;

그리고 지금은 헬퍼를 사용하는 경우이다.

Element.getHeight("first");

이 경우, 헬퍼는 어떠한 잇점도 제공하지 않는다. 지금 우리가 요소로부터 className을 제거하길 원하는가.? 이것은 (Prototype.js소스코드로 부터 얻어진) 다소 긴 방법이다.

element = $(element);
if (!element)
    return;
var newClassName = '';
var a = element.className.split(' ');
for (var i = 0; i < a.length; i++) {
    if (a[i] != className) {
        if (i > 0)
            newClassName += ' ';
        newClassName += a[i];
    }
}
element.className = newClassName;

그리고 지금은 헬퍼 함수를 사용하는 경우이다.

Element.removeClassName("elementID", "red");

멋진가.? 첫번째 예제와는 달리, 대부분의 헬퍼 함수는 공통적인 작업을 쉽게 수행하여 시간과 수고를 아낀다. 그리고 일관성을 위해, 이것은 프로젝트 도처에 Element문법을 사용하는 것이 가장 좋은 방법이 될것이다. 헬퍼 함수의 전체 목록과 그것들을 사용하는 방법을 보기 위해서, Sergio의 프로토타입 문서를 보라.

Try.these 함수

Try.these()는 다른 자바스크립트 구현물과 관계없이 브라우저를 종속되지 않고 작동하는 코드를 생성하도록 개발자를 도와주기 위한 멋진 함수이다. 객체와 브라우저 인식의 자신만의 방법대신에, 이 함수는 에러를 발생할때까지 코드의 하나의 경로를 수행하도록 시도하고 다음 경로로 교체한다.

return Try.these(
    function() {
        alert("first");
        jkgjhgjhg        //intentional error
        alert("firsterror");
        return 1;
    },
    function() {
        alert("second");
        return 2;
    }
);

위 예제에서, 첫번째 경로는 내부 에러발생시 수행을 멈출것이다. 이것을 알라. 모든것은 에러가 발생되지 전에 수행되어야 하기 때문에 이것은 우리의 코드가 신중하도록 하기 위해 중요하다. 우리는 코드가 두번 수행되지 않도록 주의해야만 한다. 전체적으로, Try.these()는 우리가 종종 사용하는 함수일뿐 아니라, 이것이 존재하고 어떻게 사용해야 하는지 아는것은 멋진 일이다.

Ajax 지원

이 라이브러리에서 Ajax지원 함수는 부족하지 않다. 그리고 나는 Prototype.js의 도움으로 Ajax애플리케이션을 생성하는 방법을 보여줄것이다. 문서로부터 우리는 다음처럼 일반적인 Ajax요청을 볼수 있다.

var myAjax = new Ajax.Request(
    url,
    {method: 'post', parameters: data, onComplete: ajax_response}
);

메소드가 post이거나 get인 지점에서, 파라미터는 이름/값 형태의 문자열이고, onComplete은 모든것이 종료되었을때 호출되어야 하는 함수이다. 핵심기능을 이해했을때, 라이브러리를 도구화하는 자신만의 함수를 생성하여 반복적인 Ajax호출을 만드는 것이 쉽다. 먼저, Ajax요청을 처리하는 간단한 함수이다.

function ajax_request(url, data) {
    var myAjax = new Ajax.Request(
        url,
        {method: 'post', parameters: data, onComplete: ajax_response}
    );
}

요청이 종료된후, 이것을 ajax_response()로 보낸다.

function ajax_response(originalRequest) {
    if(!bHasRedirect) {
        //process originalRequest.responseText;
    }
    else {
        bHasRedirect = false;
        ajax_request(originalRequest.responseText, "");
    }
}

당신이 Ajax요청을 만든후, 응답은 언제나 ajax-response()로 보내진다. 여기서 다른 Ajax요청은 bHasRedirect(전역변수)가 true로 셋팅된 경우에만 만들어질것이고 true가 아니라면 아마 코드는 함수와 originalRequest.responseText()의 전역 배열에 기반하여 수행될것이다.

PeriodicalExecuter

PeriodicalExecuter객체가 초기화되면, 이것은 주어진 기간에 특정 함수를 반복적으로 호출한다. 이것은 당신이 사이트의 Ajax부분을 자동으로 수정하길 바랄때 유용할것이다.

function periodicalUpdate() {
    new PeriodicalExecuter(refreshNews, 10);
}

function refreshNews() {
    //Ajax code to grab news and update DOM
}

PeriodicalExecuter 생성자는 첫번째 파라미터처럼 호출하기 위한 함수를 예상한다. 그리고 이것은 시간간격(초단위)이다. 비록 공통적인 setInterval()가 밀리세컨드를 다루지만 시간을 혼동하지 말라. 하지만 이 함수에서 우리는 초 단위로 다룬다. 예제는 Ajax가 복잡하다고 가정하지만, 이것은 어떤 이유로 페이지를 수정할수 있다. Prototype.js는 또한 Ajax를 다룰때 쉽게 처리할수 있는 Ajax.PeriodicalUpdater클래스를 가진다.

출처 : http://openframework.or.kr/