ExtJS 2.2x를 쓰는 경우 IE6에서 그리드 상단 메뉴의 아이콘이 아래의 그림처럼

제대로 표시되지 않는 버그가 남아 있슴을 이제사 알게 되었다.

솔직히 이 버그는 예전에 발견된 버그일뿐 아니라 2.2.1 버젼에서는 fix된 것으로 알고 있었던 터라..

IE7 이후 버젼에만 맞추고 테스트를 진행했었는데..혹여나..

다시 최신버젼을 받아봐도 IE6에서 위에 해당하는 버그가 발생하는 것을 확인할 수 있었다.

예전엔 IE7 이후버젼에 이런 증상이 있었는데 지금은 거꾸로 IE6에서 발생하다니..

 

해결 방법은 이전버젼에서 적용했던 버그 fix를 그대로 적용하면 된다.

 

.ext-ie .x-menu-item-icon {left: -24px;}

.ext-strict .x-menu-item-icon {left: 3px;}

.ext-ie6 .x-menu-item-icon {left: -24px;}

 을  css에 추가하면 된다.

 

이젠 IE6 버젼에서 정상적으로 돌아가는 것을 확인할 수 있을 것이다.

물론 IE7과  IE8, 파폭, 크롬에서도 정상작동 확인...

 

고급 자바스크립트 활용 II

WEB2.0 | 2008. 4. 2. 18:04
Posted by 시반
바로 전 기사에서는 두 가지 형태의 자바스크립트 위젯과 떠다니는 텍스트, 팝업 메뉴를 완전한 소스를 보여주면서 소개하였다. 이 기사에서는 또 다른 유용한 자바스크립트 위젯을 계속해서 소개해볼 텐데, 실제로 위젯이 어떻게 동작하는 지에 대해 집중적으로 살펴봄으로써 여러분이 그것들을 필요한 대로 손쉽게 수정할 수 있게 할 것이다. 이 기사에서 사용된 자바스크립트는 수정할 필요 없이 현재 사용되고 있는 주요 브라우저에서 모두 동작해야 한다. 별 어려움 없이 말이다…

div 태그를 이용한 이미지 토글

종종 여러분은 이미지 같은 무언가를 웹 페이지에 잔뜩 집어넣고 싶을 때가 있을 수도 있는데, 그것들을 모두 집어넣기엔 웹 페이지의 공간을 너무 많이 차지한다. 그러면 이미지 하나만 집어넣고 사용자가 스위치를 이용해서 다른 이미지로 교체하도록 하면 어떨까? 아마 이렇게 작동할 것이다:

div_toggle.html

이렇게 하는 것은 실제로 매우 간단하다. 한 가지 알아둘 것은 매번 이미지를 전환할 때마다 브라우저는 서버와 교신하지 않는다는 것이다. 하지만 이미지는 즉시 전환된다. 트릭이 무엇이냐고? 바로 이미지를 모두 HTML에 집어넣긴 하지만 한번에 하나씩만 보여주는 것이다! 이는 div 태그와 스타일을 이용해서 손쉽게 완성할 수 있다. 이 기법을 이용하면 인상적인 효과를 꽤 많이 만들어 낼 수 있으며, 이어지는 예제에서 볼 수 있을 것이다. 하지만 처음에는 지금 보여지고 있는 예제가 실제로 어떻게 작동하는 지에 대해서만 생각해 보기로 하자. 단 하나의 자바스크립트 함수만 사용하였다:
function ShowImage(page, tag)
{
    var i = 1;
    var el;
    while (el = document.getElementById(tag + i)) {
        if (i == page)
            el.style.display = 'block';
        else
            el.style.display = 'none';
        i++;
    }
}
실제 이미지들은 HTML상에 나타나야 할 위치에 놓여져 있는데, 각 이미지들은 다음과 같이 해당 div 태그에 들어있다:
<table>
    <tr valign="top">
        <td>
            <div style="display:block" id="image1">
                <img src="/onlamp/2007/08/23/graphics/pic1.jpg" />
            </div>
            <div style="display:none" id="image2">
                <img src="/onlamp/2007/08/23/graphics/pic2.jpg" />
            </div>
            <div style="display:none" id="image3">
                <img src="/onlamp/2007/08/23/graphics/pic3.jpg" />
            </div>
        </td>
        <td width="100%" align="right">
            <select onchange="ShowImage(parseInt(this.value), 'image');">
                <option selected="selected" value="1">Image 1</option>
                <option value="2">Image 2</option>
                <option value="3">Image 3</option>
            </select>
        </td>
    </tr>
</table>
위 테이블 구조는 단순히 레이아웃에 맞춰져 있는데, 기사의 논의 목적상 그런 것은 무시할 수 있다. 중요한 부분은 테이블의 첫 번째 셀 안에 들어있는 세 개의 div 태그들이다. 다른 div 태그들은 display가 none으로 설정되어 있는데 반해 첫 번째 div 태그는 display가 block으로 설정되어 있다. 비록 이전에 이미지를 서버로부터 전달받아 로컬에 저장하여 웹 페이지의 나머지 부분에 있더라도 display가 none으로 설정되어 있는 것들은 뷰에서 감춰져 브라우저 창에 그려지지 않는다. 따라서 처음에는 pic1.jpg만 보여지고 다른 두 개의 이미지는 볼 수 없다.

그런 다음 선택상자(selector box)에 onchange 이벤트가 발생할 때 자바스크립트 함수를 호출하도록 만들어 놓는다. 이렇게 하면 사용자가 선택상자에서 새로운 것을 선택 할 때 이벤트가 발생한다. 자바스크립트에는 두 개의 인자를 전달하는데, 각각 선택상자의 노드 자체에 대한 레퍼런스와 이미지를 담고 있는 div 태그의 id이다(id는 image1, image2, image3으로 모두 image로 시작한다는 것을 염두에 둔다).

함수는 보여줄 이미지를 의미하는 최근에 선택된 값을 가지고 실행된다. parseInt를 이용하여 선택된 값이 문자열이 아니라 숫자로 저장되도록 하였다. 다음으로는 첫 번째 div 태그에 대한 핸들을 가져오는데, 위 경우 image1이라는 id를 가진 것을 가져오게 된다. 만약 현재 이미지가 보여질 이미지이면 display 스타일을 block으로 지정하고 나머지 것들은 none으로 지정한다. 그리고 나서 더 이상 태그를 찾을 수 없을 때까지 다음 태그들을 처리한다.

그러므로 드롭 다운 박스에 새로운 항목들이 선택될 때마다 해당 div 블록이 보여지며 다른 것들은 모두 감춰진다. 이미지들은 모두 웹 페이지상의 동일한 물리적 공간을 공유하고 있는데, 왜냐하면 HTML내에서 서로서로 바로 옆에 위치해 있기 때문이다. 하지만 물론 꼭 이렇게 해야 하는 것은 아니므로 이미지들을 페이지의 서로 다른 영역에 뿌려놓고 원한다면 선택하는 것에 따라 다양한 위치에 그림을 나타나게 할 수도 있었다. 이와 비슷하게 이미지에도 어떠한 제약사항이 가해지는 것도 아니라서, 죄다 div 태그 사이에 집어넣고 마우스 클릭 한번으로 감추고 보이게 할 수도 있다. 이는 여러분이 일반적으로 집어넣는 것 보다 훨씬 더 많은 정보를 웹 페이지에 집어넣을 수 있도록 해주며 사용자는 아무런 스크롤도 할 필요가 없다.

탭 : div 좀 더 갖고 놀기

div 태그를 이용하는 다른 독창적인 예제를 통해 계속 진행해 보자. 종종 정보가 담겨있는 여러 개의 "탭(tab)"이 포함된 웹 페이지를 만들어 보고 싶을 때가 있다. 마치 요즘 사용되는 대부분의 웹 브라우저에서 제공하는 탭 브라우징 기능이 작동하는 것 마냥 탭을 클릭하면 탭에 들어있는 정보를 보여주고 다른 부분들은 감춰진다. 하지만 일반적으로 이처럼 HTML상의 탭을 클릭하면 페이지를 다시 불러오기 때문에 확실히 인터페이스의 자연스러움이 흐트러지게 된다. 정보가 즉각적으로 나타날 때 좀 더 멋있게 할 수는 없을까? 이전 예제에서 배웠던 매우 사소한 트릭을 이용하면 그렇게 할 수 있다. 한번 해보자:

tab_source.html

놀랄 것도 없이 이 예제는 이전 예제에서 사용했던 것과 정확히 동일한 자바스크립트 함수를 사용하고 있고 있는데, 전혀 다른 효과를 보여주고 있다. 나머지 부분은 몇 가지 단순한 CSS 규칙만으로 이루어진다. 이제 이 예제의 HTML을 살펴보기로 하자.
<div style="display:block" id="tab1">
    <ul class="tab">
        <li class="tab_selected" onclick="ShowImage(1, 'tab');">
            Summary
        </li>
        <li onclick="ShowImage(2, 'tab');">
            Details
        </li>
        <li onclick="ShowImage(3, 'tab');">
            Known Issues
        </li>
    </ul>
    <p>
        Introducing the new, improved multi-widget.  It slices, it dices, it even does
        your taxes!  Order yours today!  Call now: 555-WIDG
    </p>
</div>

<div style="display:none" id="tab2">
    <ul class="tab">
        <li onclick="ShowImage(1, 'tab');">
            Summary
        </li>
        <li class="tab_selected" onclick="ShowImage(2, 'tab');">
            Details
        </li>
        <li onclick="ShowImage(3, 'tab');">
            Known Issues
        </li>
    </ul>
    <p>
        The multi-widget is a sophisticated piece of complex machinery designed by the
        country's leading nuclear physicists.  Order yours today and you will quickly
        learn how easy it is to do just about anything in no time, thanks to our patented
        EZ-Widge technology.
    </p>
    <p>
        Motor: 5HP<br />
        Dimensions: 8" x 5" x 2"<br />
        Weight: 212 g<br />
        Radioactivity: negligible
    </p>
</div>

<div style="display:none" id="tab3">
    <ul class="tab">
        <li onclick="ShowImage(1, 'tab');">
            Summary
        </li>
        <li onclick="ShowImage(2, 'tab');">
            Details
        </li>
        <li class="tab_selected" onclick="ShowImage(3, 'tab');">
            Known Issues
        </li>
    </ul>

    <ul>
        <li>Do not use multi-widget near open flames</li>
        <li>Do not run while holding multi-widget</li>
        <li>Do not taunt multi-widget</li>
        <li>
            Multi-widget may, under certain as yet undetermined circumstances,
            spontaneously explode.  We hereby disclaim any libaility for personal injury
            caused as a result of multi-widget; for your safety, we recommend wearing
            body armor while handling multi-widget.
        </li>
    </ul>
</div>
마치 이전 예제에서 각각의 이미지 하나당 하나의 div를 가졌던 것처럼3개의 div 섹션(각 탭 당 하나씩)을 가지고 있음을 알아둔다. 그리고 이번에도 첫 번째 블록에만 display:block으로 지정하고 나머지 것들은 display:none으로 지정하여 처음에는 오직 첫 번째 블록만 보이도록 한다. 이러한 각 섹션들은 세 개의 탭을 그림으로써 시작하는데, 선택된 블록만 다른 것과 블록과 다른 색상을 띤다. 그렇게 하여 실제로는 각 탭을 선택할 때마다 세 개의 탭을 모두 몇 번이고 다시 그리게 되는 셈이다. 탭에 들어가는 내용은 임의의 HTML이 될 수 있다. 기억해둘 것은 내용은 오직 한번만 보여지고, 실제 탭의 HTML만 수회에 걸쳐 반복되기 때문에 "낭비되는(wasted)" 공간을 최소화할 수 있는 것이다.

각 항목에 onclick 이벤트가 발생하면 showImage 자바스크립트 함수가 호출된다는 것을 알아둔다. 첫 번째 예제에서 살펴본 것과 같이 showImage 함수는 인자로 전달된 하나만 제외하고 나머지 모든 div 섹션들을 숨긴다. 이와 같이 여기에서는 이 함수를 여러분이 클릭한 탭만을 보여주고 다른 나머지 것들은 감추는데 사용한다. 탭을 적절하게 그리는 데에는 실질적으로 CSS나 스타일을 사용하며 CSS에는 tab과 tab_selected라는 이름의 두 클래스를 정의하였다. 전자는 특별한데가 없는 전체 탭에 적용되는 것이고, 후자는 현재 선택된 탭에만 적용되는 것이다. CSS의 내용은 다음과 같다:
ul.tab {
    margin: 0;
    padding: 3px 0;
    border-bottom: 1px solid #778;
    font-weight: bold;
}

ul.tab li {
    display: inline;
    padding: 3px 0.5em;
    margin-left: 3px;
    border-top: 1px solid #778;
    border-left: 1px solid #778;
    border-right: 1px solid #778;
    border-bottom: none;
    background: top repeat-x #89aac7;
    white-space: nowrap;
    color: white;
    cursor:pointer;
}

ul.tab li.tab_selected {
    background: #fff;
    border-bottom: 1px solid #fff;
    color: black;
}
첫 번째 섹션은 ul 태그와 전체 탭 바에 적용된다. 첫 번째 섹션은 margin과 padding을 지정하여 무조건 왼쪽위로 지정하고 border가 탭 바의 바닥에 그려지게 한다. 적당히 줄을 맞추기 위해 padding이 필요하며, 탭 바의 텍스트는 모두 진하게 표시하였다.

다음 섹션은 탭 바에 들어있는 모든 li 태그에 적용된다. 아마 display:inline이 가장 중요한 속성일텐데, 목록을 수직이 아닌 수평으로 만들어 주기 때문이다. 다시 한번 padding과 margin을 이용하여 탭을 일렬로 세우고 탭 사이사이의 여백을 맞춘다. border 속성은 상단과 탭 좌우를 그린다(바닥은 ul 태그로 그려짐을 떠올려본다). 마지막으로 배경 및 전경색상을 지정하고 텍스트 줄바꿈은 비활성화 하였다.

마지막 섹션은 현재 선택된 탭에만 적용되는데, 두 번째 섹션에 정의되어 있는 모든 설정을 재정의한다. 바뀐 것은 탭의 배경색상과 전경색상이며 ul 태그의 검정색 바닥 경계선을 흰색 바닥 경계선으로 그려줄 뿐만 아니라 선택된 탭을 눈에 띄도록 해준다. 이는 선택된 탭이 다른 탭 앞으로 튀어 나온 것처럼 착각하게 만든다.

이 예제에서 모든 탭의 내용은 모두 페이지 안으로 불러들여져 저장되므로 탭을 클릭하면 거의 즉각적으로 새로운 정보가 만들어지며 페이지를 다시 불러오지 않기 때문에 주의가 분산되지도 않는다. 매우 간단한 자바스크립트 함수와 CSS를 조금 사용하여 실로 매우 인상적인 효과를 거둘 수 있었다.

훨씬 고급스러운 div 트릭

앞에서 배웠던 트릭을 이용하는 유용한 애플리케이션의 마지막 예제로서 많은 양의 내용이나 목록을 요약하여 사용자가 관심있는 목록만을 열어볼 수 있도록 하는데 사용할 수 있는 다음의 예제를 만들어 보기로 하자:

advanced_div.html

아래는 위 예제의 소스이다:
<div style="display:block;" id="colors1">
    <table style="background:#eeeebb">
        <tr>
            <td>
                <img src="/onlamp/2007/08/23/graphics/expand.jpg" style="cursor:pointer;"
                alt="Click to Expand" title="Click to Expand" 
                onclick="ShowImage(2, 'colors');" />
            </td>
            <td>
                Choice of four widget colors
            </td>
        </tr>
    </table>
</div>
<div style="display:none;" id="colors2">
    <table style="background:#eeeebb">
        <tr valign="top">
            <td>
                <img src="/onlamp/2007/08/23/graphics/collapse.jpg" style="cursor:pointer;"
                alt="Click to Collapse" title="Click to Collapse" 
                onclick="ShowImage(1, 'colors');" />
            </td>
            <td>
                <ul>
                    <li>blue</li>
                    <li>green</li>
                    <li>red</li>
                    <li>brown</li>
                </ul>
            </td>
        </tr>
    </table>
</div>
이제 이 예제가 어떻게 작동하는지 꽤 명확하게 알 수 있어야 한다. 이번에도 위에서는 두 개의 div 블록을 포함하고 있는데, 하나는 접혀 있는 내용에 펼침 버튼이 있는 것이고, 다른 하나는 완전히 펼쳐진 내용에 닫기 버튼이 있는 것이다. 처음에는 닫힌 버전(display:block)만을 보여주고 이미지의 onclick 콜백을 이용하여 div 블록이 바뀌는 것을 감지한다. 블록에는 colors1과 colors2라는 id가 주어지는데, 그렇게 하여 앞서 작성했던 ShowImage 자바스크립트 함수로 손쉽게 전환할 수 있다.

드래그 앤 드롭과 맞바꾸기(swap)

이제 div 태그에 대해 멀미날 정도로 조사해 보았으므로 이번에는 조금 다른 것에 관해 알아보기로 하자. 이 예제에서는 마우스로 텍스트(혹은 이미지)를 드래그 앤 드롭할 수 있는 메소드를 보여줄 것이다. 이러한 메소드는 자바스크립트 게임이나 좀 더 중요한 목적, 예를 들면 여러분이 한 페이지에 들어있는 이미지의 순서를 바꾸거나 할 때 사용할 수 있다. 다음 예제에서는 서로 위에 포개져 있는 세 개의 이름을 드래그 앤 드롭하여 이름의 위치를 바꿔보도록 하겠다. 여러분이 John과 Jane은 문제없이 위치를 바꿀 수 있겠지만, Bill은 다른 것과 서로 위치를 바꿀 수 없을 것이다. 왜냐하면 Bill은 항상 말썽만을 일으키는 녀석이기 때문이다.

draggable.html

이 예제는 지금껏 보여주었던 것보다는 더 많은 양의 코드를 필요로 하긴 하지만 상당히 직관적이기도 하다. 다른 예제와는 달리 이번 예제는 전역 마우스 이벤트를 이용한다. 구체적으로 말하자면 이 예제는 트리거되는 세 개의 콜백 함수(마우스가 눌렸을 때, 마우스가 이동할 때, 마우스 버튼을 놓았을 때)에 의존한다. 이러한 종류의 전역 이벤트를 사용하는 것의 단점은 만약 여러분이 한꺼번에 여러 가지를 이어서 할 경우 상당히 곤란한 경우를 겪을 수도 있다는 것이다. 그러므로 여러분은 이러한 전역 이벤트를 사용하는 것을 최소화해야 하며 페이지당 기껏해야 하나 혹은 두 개만을 갖도록 해야 한다. 특히 이러한 예제의 경우 전역 이벤트는 상당히 필수적이다. 한 문단씩 살펴보기로 하자.
// 콜백을 지정
document.onmousedown = mousedown;
document.onmousemove = movemouse;
document.onmouseup   = mouseup;
var lastobj; // 마지막으로 마우스를 올려놓았던 드래그 가능한 객체
var isdrag; // 객체를 드래그 하고 있을 경우 True
다음 코드에서는 세 개의 콜백 함수들을 초기화한다. mousedown과 mousemove는 각각 사용자가 마우스 버튼을 클릭할 때와 이동할 때 호출될 것이며, mouseup은 왼쪽 마우스 버튼을 놓았을 때 트리거될 것이다. 또한 여기에서는 두 개의 전역 변수가 필요한데, 첫 번째 것은 가장 최근에 마우스를 올려놓았던 객체를 추적하기 위한 것이며, 두 번째는 현재 객체를 드래그하고 있을 경우 true를 값으로 가지는 플래그 변수이다.
// 다음 코드는 여러분이 텍스트를 클릭했을 때 
// 드래그할 수 있는 텍스트를 강조하지 않도록 한다.
// 테이블은 drag_drop이라는 id를 가진 모든 드래그 
// 가능한 텍스트를 포함한다.

window.onload = function()
{
    var e = document.getElementById('drag_drop');
    if (e) {
        if (moz)
            e.onmousedown = function () { return false; } // mozilla
        else
            e.onselectstart = function () { return false; } // ie
    }
}
페이지가 로딩되자마자 위 함수가 실행되는데, 드래그할 수 있는 객체에 대해 클릭할 경우 보통 우리가 텍스트를 클릭했을 때 일어나는 일처럼 텍스트를 강조하지 않도록 한다. 이는 일반적으로 텍스트를 강조하도록 요청되는 함수를 빈 함수로 재정의하여 강조하지 않도록 만들 수 있다.
// 객체의 id에 근거하여 두 객체간에 맞바꾸기가 허용되는지를 확인한다.
// 각각의 드래그할 수 있는 항목들의 짝에 대해 맞바꾸기를 허용하거나 금지하도록 하는
// 조건을 여러분이 원하는 대로 변경한다.
function allowswap(a,b)
{
    if (a.id == "dragdropa" && b.id == "dragdropb" || a.id == "dragdropb" && b.id 
    == "dragdropa")
        return true;
    return false;
}

// 객체가 드래그할 수 있는 것이면 true를 반환 - 필요에 맞게 변경하도록 한다.
function isdraggable(obj)
{
    if (obj.id.substr(0,8) == "dragdrop")
        return true;
    return false;
}
두 개의 유틸리티 함수도 필요한데, 주어진 두 객체에 대하여 allowswap함수는 두 객체가 서로 맞바꿀 수 있을 경우 true를 반환하며, 그렇지 않을 경우 false를 반환한다. 확실히 여기에 들어있는 조금 복잡한 로직을 이용하여 여러분은 꽤 재미있는 일을 할 수 있다. isdraggable함수는 주어진 객체가 드래그 가능할 경우true를 반환한다. 이 예제의 취지상 객체가 드래그할 수 있는지를 단순히 객체의 id가 dragdrop으로 시작하는지 근거하여 판단하고 있는데, 물론 여러분은 그렇지 하지 않을 수도 있으며, 여러분이 원하는 대로 변경할 수도 있다. 가령 특정 class로 드래그할 수 있음을 나타낼 수도 있는데, 이 예제의 취지상 위에서 했던 것만으로도 충분하다.
// 마우스 버튼이 놓였을 경우의 콜백. 이 함수는 항목이 드래그 할 수 있는지를 확인하고,
// 드래그 할 수 있으면 프로세스를 초기화한다.
function mousedown(e) 
{
    var obj = moz ? e.target : event.srcElement;
    // DOM 트리를 추적하여 클릭한 항목이 드래그 할 수 있는지를 확인한다.
    // 이렇게 하면 예를 들면 TD를 감싸고 있는 TR이 드래그 할 수 있는 객체일 경우에도
    // 여러분이 클릭할 수 있다.
    while (obj.tagName != "HTML" && obj.tagName != "BODY" && !isdraggable(obj)) {
        obj = moz ? obj.parentNode : obj.parentElement;
    }
    if (isdraggable(obj)) {
    // 만약 드래그 할 수 있으면 전역 플래그 변수를 설정하여 이 객체를 추적하도록 하고,
    // 또한 객체의 포인터를 전역 변수에 저장한다(dragobj).
        isdrag = true;
        dragobj = obj;

        // origx, origy는 드래그되는 객체의 원래 시작 위치임.
        origx = dragobj.style.left;
        origy = dragobj.style.top;

        // x,y는 window내의 절대 좌표
        x = moz ? e.clientX : event.clientX;
        y = moz ? e.clientY : event.clientY;

        // offsetX, offsetY는 여러분이 클릭한 객체가 정확히 어디에 있는지에 의존한다.
        // 따라서 여러분이 객체의 중앙을 클릭할 경우, 객체는 그 위치에서
        // 마우스에 '덧붙여지는데(attached)', 예를 들면 좌상단 모서리에 덧붙여지지는 않는다.
        offsetX = moz ? e.layerX + 2: event.x + 2;
        offsetY = moz ? e.layerY + 2: event.y + 2;
    }
}
마우스 버튼이 눌렸을 때 호출되는 mousedown 함수가 코드의 첫 번째 주요 부분이다. 무언가가 클릭되면 그것이 드래그 할 수 있는지를 확인한다. 만약 드래그 할 수 없다면 그것의 부모 노드 등이 드래그 할 수 있는지를 확인한다. 이렇게 하는 이유는 여러분이 무언가를 클릭했을 때 브라우저가 일반적으로 DOM 트리에서 가장 낮고 깊이가 깊은 항목의 핸들을 반환할 것이기 때문이다. 그렇기 때문에 예를 들어p 태그를 감싸고 있는 span 태그가 드래그 할 수 있는 것으로 표시되어 있을 경우, 그러한 태그 사이의 텍스트를 클릭했을 때 여러분은 드래그 할 수 있는 것으로 표시되어 있지는 않은 p 태그의 핸들을 가져오게 된다. 그러나 부모 노드를 확인하여 실제로 그 노드가 드래그 할 수 있는 항목의 자식인지를 확인하여 실제로는 드래그 할 수 있는지 여부를 알아낼 수 있다.

무언가 드래그 할 수 있는 것을 클릭했다고 가정하면 전역 플래그 변수를 true로 설정하고 그 객체를 dragobj에 저장한다. 또한 몇 가지 좌표도 저장하는데, 이러한 좌표에는 dragobj의 원래 위치, 클릭한 마우스의 상대 위치 및 클릭한 절대 위치가 포함된다.
// 마우스가 이동할 때의 콜백. 이 함수는 여러분이 맞바꿀 수 있거나 맞바꿀 수 없는 객체위에서
// 마우스를 움직일 때 커서를 변경할 것이다.
function movemouse(e)
{
    // 현재 객체를 드래그하고 있는지를 확인
    if (isdrag) {
        // 만약 현재 객체를 드래그하고 있다면 드래그되는 객체의 위치를 마우스가 처음 클릭한 이후로
        // 상대적으로 마우스가 움직인만큼 지정한다.
        dragobj.style.left = moz ? origx + e.clientX - x 
              + offsetX + 'px' : origx + event.clientX - x + offsetX;
        dragobj.style.top  = moz ? origy + e.clientY - y + offsetY 
              + 'px' : origy + event.clientY - y + offsetY;
        var obj = moz ? e.target : event.srcElement;
    
        // 지금 맞바꿀 수 없는 엘리먼트상에 있을 경우 커서 스타일을 
        // 맞바꿈이 금지되어 있음을 보여주는 것으로 변경한다.
        if (obj != dragobj && isdraggable(obj) && !allowswap(dragobj,obj)) {
            obj.style.cursor = 'wait';
            // 객체에 대한 핸들을 전역변수에 저장하여 커서를 나중에 초기화할 수 있도록 한다.
            lastobj = obj;
        }
        else if (lastobj)  // 드래그할 수 없는 객체의 이동이 끝나는대로 커서를 초기화한다.
            lastobj.style.cursor = 'pointer';
        return false;
    }
    else {
        // 간혹 드롭 아이콘으로 갇힐 수 있는데, 그러므로 드래그하고 있지는 않지만 드래그할 수 있는
        // 항목을 전달할 때 안전하게 하기 위해 커서를 복원한다.
        var obj = moz ? e.target : event.srcElement;
        if (isdraggable(obj))
            obj.style.cursor = 'pointer';
    }
}
마우스가 이동할 때마다 먼저 무언가가 드래그되고 있는지를 확인한다. 무언가가 드래그되고 있다면 그 객체가 어디로 드래그 되어야 하는지를 계산하여(아무튼 객체가 스스로 알아서 마우스를 따라다니는 것은 아니다!) 그에 맞게 객체를 이동시킨다. 또한 다른 드래그 할 수 있는 객체 위에 마우스를 올려놓았는지도 확인한다. 그럴 경우 allowswap 함수를 호출하여 맞바꾸기를 할 수 있는지를 결정한다. 맞바꾸기를 할 수 없다면 커서는 "대기(wait)" 모양으로 바꾼다(컴퓨터마다 모양이 다양하긴 하지만 표준 대기 커서이다). 객체를 서로 맞바꿀 수 있거나 드래그 할 수 있는 객체 위에 마우스를 올려놓지 않았다면 커서를 그대로 두고, 이전에 모양을 바꾸었다면 다시 모양을 복원한다.

한 가지 추가적으로 알아두어야 할 것은 드래그할 수 있는 객체 위에 마우스를 올려 놓더라도 현재 아무것도 드래그하고 있지 않으면 그대로 커서를 원래대로 복원한다는 것이다. 왜냐하면 사용자가 마우스를 얼마나 빨리 이동하고 버튼을 놓는 등의 동작을 하느냐에 따라 간혹 커서가 "대기" 상태에 갇힐 수 있기 때문이다. 그렇기 때문에 위에서 언급한 커서를 복원하는 로직은 failproof하지는 않다.
// 마우스 버튼을 놓았을 때의 콜백이며 맞바꾸기가 일어나야 하는지를 확인하며
// 맞바꾸기가 일어나지 말아야할 경우 드래그되는 개체를 원래 시작위치로 되돌려 보낸다.

function mouseup(e)
{
    if (isdrag) {  // 무언가가 드래그되고 있다면

        // 마우스 버튼이 놓여진 객체를 획득한다.
        var obj = moz ? e.target : event.srcElement;

        // 맞바꿀 수 있는 객체에 대해 마우스가 놓여졌는지를 확인한다.
        if (obj != dragobj && isdraggable(obj) && allowswap(dragobj, obj)) {

            // 맞바꾸기가 허용된 경우, 색상, 툴팁, 드래그 되는 객체의 내용을
            // 마우스가 놓여진 객체의 것들과 맞바꾼다.
            var htm = obj.innerHTML;
            obj.innerHTML = dragobj.innerHTML;
            dragobj.innerHTML = htm;

            var col = obj.style.color;
            obj.style.color = dragobj.style.color;
            dragobj.style.color = col;

            var titl = obj.title;
            obj.title = dragobj.title;
            dragobj.title = titl;

            // 현재 드래그하고 있는 객체(dragobj)의 위치를 다른 객체(obj)의 위치로 지정하고
            // obj를 dragobj가 드래그되기 전에 dragobj의 원래 위치(origx, origy)로 이동한다.
            dragobj.style.left = obj.style.left;
            dragobj.style.top = obj.style.top;
            obj.style.left = origx;
            obj.style.top = origy;
        }
        else {
            // 맞바꾸기가 일어나지 않으므로 드래그되는 객체를 원래의 시작 지점으로 돌려보낸다.
            dragobj.style.left = origx;
            dragobj.style.top = origy;
        }

        // 커서가 movemouse에서 바뀌었을 경우 커서를 포인터로 복원한다.
        if (lastobj) {
            lastobj.style.cursor = 'pointer';
        }
    }
    isdrag = false;  // 현재 아무것도 드래그되는 것이 없음
}
mouseup이벤트는 객체를 드래그하는 동안 마우스가 놓여졌는지에 관해 가장 상세한 조사를 벌인다. 드래그할 수 있는 객체를 놓을 경우 allowswap 함수를 이용하여 맞바꾸기가 가능한지를 확인한다. 바꾸기가 가능하다면 두 객체의 텍스트 내용, 색상, 그리고 툴팁(title 속성)을 서로 맞바꾼다. 이 시점에서 여러분은 여러분 목적에 맞게 단순히 객체의 모든 속성들을 맞바꾸길 선호할지도 모르겠다. 그리고 나서는 드래그되고 있는 객체를 마우스를 놓은 객체가 위치한 곳까지 이동시킨 후, 이번에는 마우스를 놓은 객체를 드래그되는 객체의 원래 시작지점으로 이동시킨다. 이리하여 맞바꾸기가 완료된다. 반면 맞바꾸기가 금지되어 있으면 단순히 드래그 되는 객체를 원래의 시작지점으로 돌려 보낸다. 두 경우 모두 마우스 커서가 movemouse 상태의 "대기" 커서로 변했을 경우 마우스 커서를 복원하고 더 이상 객체를 드래그하고 있지 않다는 것을 나타내기 위해 isdrag 플래그 변수를 초기화한다.

마지막으로 객체를 인스턴스화하는 것은 매우 쉽다. 드래그 할 수 있는 객체의id가 dragdrop으로 시작한다는 것만 기억하면 된다:
<table id="drag_drop" align="center" style="font-size:150%; color:green; 
    background-color:#88ccff; white-space: nowrap;">
  <tr>
    <td>
      <span id="dragdropa" style="cursor: pointer; position: 
      relative; color: #ff0000" title="John Doe">John</span>
    </td>
  </tr>
  <tr>
    <td>
      <span id="dragdropb" style="cursor: pointer; position: 
      relative; color: #a0522d" title="Jane Smith">Jane</span>
    </td>
  </tr>
  <tr>
    <td>
      <span id="dragdropc" style="cursor: pointer; position: 
      relative; color: #00aa00" title="Bill Schwartz">Bill</span>
    </td>
  </tr>
</table>

편의상 테이블에 객체가 위치해 있을 경우 각기 다른 색상을 띠도록 하였는데, 중요한 점은 드래그할 수 있는 항목의 id가 allowswap에서도 참조되며 style 속성이 position:relative라는 사실이다. 이 공식은 자바스크립트에서 객체들의 위치를 계산하여 상대적인 위치를 추정하는데 사용되었다. 또한 감싸고 있는 테이블의 id는 drag_drop인데, window.onload 함수의 맨 위에서 참조되고 있다는 것도 알아두도록 한다.

요약

대체로 앞서의 예제들은 웹 페이지의 일부를 나누거나 선택적으로 보이게끔 하는 데 있어 다소 창의적인 방식으로 div 태그가 사용될 수 있음을 보여주고 있다. 드래그 앤 드롭 예제는 요즘 볼 수 있는 대부부의 고급스런 웹 페이지에서 볼 수 있는 상당히 강력한 개념을 정말로 간단하게 보여주는 예제의 하나일 뿐이다. 거기에 조금만 더 작업을 하면 예를 들어 완전히 커스터마이즈가 가능한 홈 페이지를 만들어 여러분이 각종 뉴스 피드나 이미지, 그리고 핵심 컨텐츠들을 드래그 하고 서로 위치를 바꿀 수 있도록 할 수도 있다. 여러분의 상상력만이 유일한 제약사항일 뿐이다!


저자 Howard Feldman은 퀘벡주의 몬트리올에 위치한 Chemical Computing Group의 연구원이다.

 

 

제공: 한빛 네트워크
저자: Howard Feldman
역자: 이대엽
원문: Advanced JavaScript II

 

고급 자바스크립트 활용Ⅰ-Ⅰ

WEB2.0 | 2008. 4. 2. 18:01
Posted by 시반
웹 애플리케이션

컴퓨터 시대의 초창기때부터 서로 다른 플랫폼간의 소프트웨어 상호 운용성은 항상 관심의 대상이 되어 왔다. 가능한한 이용자층을 넓게 확대하기 위해, 업체들은 유명한 소프트웨어 프로그램을 하나의 장치에서 또 다른 장치로 옮겨왔고, 이것은 주로 몇개월이 걸리는 작업이거나, 가끔 새로운 하드웨어나 운영체제 상에서는 완전히 재작성 되기도 했다. 컴퓨터가 점점 더 강력해지고 C와 C++ 같은 언어들이 대부분의 플랫폼 상에서 사용가능한 표준이 되어감에 따라, 프로그램을 한번만 작성하여 원하는 만큼의 많은 시스템에서 사용할 수 있게 컴파일 하기가 더 쉬워졌다. C 컴파일러를 가지고 있기만 하면 소프트웨어를 빌드할수 있고 의도한대로 작동할 수 있다.

그러나, 그래픽 유저 인터페이스(GUI)를 가진 소프트웨어가 표준화 되면서 얘기가 달라졌다. Mac에서의 GUI는 윈도나 다양한 유닉스상의 그것과 틀려보였다. 물론 Tcl/Tk이나 wxWidgets같은 이른바 "위젯 툴킷"이라 불리는 것들은 C++, 파이썬, 펄과 같은 많은 유명한 언어들과 연결되어 윈도, 리눅스, 맥OS X, 그리고 기타 운영체제에서도 (거의) 똑같은 동작을 하는 플랫폼 독립적인 GUI를 만들수 있게 하기는 하다. 그러나 오늘날에는 거의 모든 장치에 매우 강력한 GUI 해석기가 존재한다. 바로 웹 브라우저다.

웹 브라우저는 처음에는 사용자들에게 단순히 마크업을 만족스러운 방법으로 보여주는데 유용했지만, 지금은 놀라울 정도로 복잡한 소프트웨어 인터페이스로서 실행될 수 있을 정도로 발전해왔고 C/C++과 다른 고수준 언어들로 쓰여진 소프트웨어들과도 견줄만 하다. 이것은 대체로 자바스크립트 지원과 웹 2.0기술 덕택이다. 모든 플랫폼상의 거의 모든 브라우저가 이 스크립트 언어의 일반적인 하위집합을 지원하며, 이전보다 플랫폼 독립적인 애플리케이션을 만들기가 더 쉬워졌다.

자바스크립트 툴킷

최근 몇몇 자바스크립트 툴킷이 야후, 구글, 도조와 같은 곳들에서 사용가능해졌다. 위에서 언급한 위젯 툴킷들과 매우 흡사하게, 이것들은 메뉴, 캘린더, 트리와 같은 다양한 위젯에 대한 자바스크립트 루틴을 제공하며, 웹사이트나 웹 애플리케이션에 쉽게 도입할 수 있게 허용한다. 여기 아주 조금만 요약해 보도록 한다.

툴킷은 웹페이지에 흥미로운 요소를 더하기 위해 좋고, 많은 이점을 가지고 있다. 이것들은 많은 브라우저 상에서 테스트 되었으며, 모든 일반적인 브라우저들에서 대부분 작동한다. 일부는 문서화가 잘 되어 있으며, 재밌는 웹페이지들을 순식간에 만들 수 있게 한다. 그러나, 이것들은 페이지 크기에 추가적인 몇백 킬로바이트를 더함으로써 불필요하게 거대해질수도 있고, 새로운 브라우저에 대한 지원이 추가되길 기다려야 할수도 있다. (예를 들어, 몇몇가지는 아직 IE7에서 작동하지 않는다.) 또한, 많은 회사들이 그것과 관련한 책임의 부족과 디버깅의 어려움 등을 이유로 오픈소스 소프트웨어를 사용할 수 없거나 사용하지 않을 것이다.

이 일련의 글들은 향상된 자바스크립트 테크닉을 사용한 튜토리얼 역할을 하기 위해 쓰여졌고, 이러한 툴킷들과 매우 비슷하게 여러 브라우저들과 호환되는 위젯을 만드는 법을 (완전한 소스를 가지고) 설명할 뿐만 아니라, 그것이 어떻게 작동하는지에 대해 자세히 설명하고 그럼으로써 여러분이 자신만의 것을 만들 수 있도록 할 것이다. 메뉴, 탭, 트리와 같은 것들을 구현하는 법에 대한 예제는 웹상에 많이 있다. 그러나 많은 것들이 극히 형편없게 작성되어 있거나 브라우저간 호환되지 않게 되어 있다. 자바스크립트, CSS, DOM, HTML에 대한 더 나은 온라인 레퍼런스 중의 하나가 www.w3schools.com이다. 만약 이 글상에서 친숙하지 않은 HTML/CSS 태그나 자바스크립트 함수를 본다면 이 사이트를 참조할 것을 권한다. HTML DOM에 대한 튜토리얼도 여기서 볼 수 있다. 앞으로 논의될 항목에는 팝업 메뉴, 플로팅 메시지, 드래그 & 드롭 객체, XML HTTP (페이지를 다시 로딩하지 않고 페이지 내용을 동적으로 바꿈) 등이 있다.

언급될 함수들은 윈도XP상의 IE7과 파이어폭스 2.0에서 테스트 되었지만 최근의 모든 브라우저에서 대부분 작동해야 함을 지적할 필요가 있다. 모든 브라우저 특화된 코드들은 본문 중에 특별히 짚어줄 것이다. 또한 자바스크립트와 DOM을 가지고 같은 목표를 달성하는 방법에는 여러가지가 있음을 명심하라. 다음 예제들은 그 중 한가지 방법을 제공하지만 모든 경우에 가장 빠르거나 가장 좋은 방법은 아닐 수 있다. 예제들은 단순성과 기능성을 가지고 읽기에 편안하게 작성되었다.

자바스크립트의 마법

다음에 보게 될 첫번째 예제는 브라우저 창이 스크롤 될 때에도 한 곳에 머물러 있는 떠있는 텍스트(혹은 이미지)를 만드는 법이다. 이것은 웹 애플리케이션에서 "잠시만 기다리세요"와 같은 메시지를 사용자에게 표시하거나 웹 페이지에 항상 표시되는 워터마크 등을 만드는데 사용할 수 있다. 이것은 자바스크립트 코드 몇 줄로 만들 수 있다:
<span id="testmsg" style="position: absolute; visibility: hidden; background: red;"
>This is a test?</span>

<form action="" method="get">
 <input name="submit" type="submit" value="Hide Message" onClick="Message_Display
('testmsg', 0, 700, 50); return false;" />
 <input name="submit" type="submit" value="Show Message" onClick="Message_Display
('testmsg', 1, 700, 50); return false;" />
</form>
이것은 다음 두개의 자바스크립트 함수로 만들 수 있다.
var ie = document.all;
var moz = document.getElementById && !document.all; 
var intr;

function Message_UpdatePos(msg, dy) {
    var el = document.getElementById(msg);
    if (ie) {
        el.style.pixelTop = document.body.scrollTop + dy;
    }
    else if (moz) {
        el.style.top = window.pageYOffset + dy + 'px';
    }
}

function Message_Display(msg, vis, dx, dy) {
    var el = document.getElementById(msg);

    // 메시지 위치

    if (ie) {
        el.style.pixelTop = document.body.scrollTop + dy;
        el.style.pixelLeft = document.body.clientWidth - dx;
    }
    else if (moz) {
        el.style.top = window.pageYOffset + dy + 'px';
        el.style.left = window.innerWidth - dx + 'px';
    }
    if (vis) {  // 표시하거나
        el.style.visibility = "visible";
        intr = setInterval("Message_UpdatePos('" + msg + "', " + dy + ")", 1);
    }
    else {  // 숨긴다
        el.style.visibility = "hidden";
        if (intr)
            clearInterval(intr);
    }
}
메시지 자체는 span 태그가 허용되는 페이지상의 모든 곳에서 인스턴스화 될 수 있다:
<span id="testmsg" style="position: absolute;
visibility: hidden; background: red;">This is a test…</span>
그러면 버튼은 단순히 다음과 같이 구현하여:
onclick="Message_Display('testmsg', 1, 700, 50); return false;"
메시지를 켜거나
onclick="Message_Display('testmsg', 0, 700, 50); return false;"
다시 끌 수 있다.

Message_Display에 전달하는 인수들은 메시지 텍스트를 가지는 span 태그의 id, 메시지를 보이게 할 것인지 안보이게 할 것인지를 가리키는 Boolean 값, 그리고 메시지가 위치해야할 브라우저 윈도의 우상단으로부터의 x, y 거리(이 경우에는 우측에서 700px, 상단에서 50px)이다. 여기에서의 키는 span 태그의 스타일이다. 절대 포지셔닝을 이용하여 메시지를 페이지의 나머지로부터 띄워서 표시하고 페이지의 나머지 흐름에 고정되지 않게 할 수 있다. 왜 span 태그가 사용되었는지도 알아두어야 한다. span 태그나 div 태그 둘 다 "아무것도 하지 않는" 태그들이며 문서상에서 각각 수평, 수직적으로 블록의 윤곽을 그리는데 사용한다. 이것들은 보통 문서에서 보이지 않는 효과를 가지고 있고, 그렇기 때문에 전체적인 외양을 변화시키지 않고도 특정한 스타일로 블록을 감싸는데 사용될 수 있다. 그러므로 이것들은 자바스크립트 위젯을 만들때 매우 간편하다.

이 함수는 다음과 같이 작동한다. 먼저 getElementById를 사용하여 메시지 span 태그에 대한 핸들을 얻어낸다. getElementById는 태그에 대한 포인터를 얻어내는 가장 쉬운 방법이다. 다음 단계는 인터넷 익스플로러 (ie)와 파이어폭스/모질라 (moz)에서 다르긴 하지만 둘 다 메시지를 원하는 위치(dx, dy)에 재위치 시키기 위한 같은 목적을 달성한다. 메시지는 visibility 스타일을 사용하여 켜거나 끌 수 있다. 마지막 라인은 자바스크립트 타이머에 대한 설명이 좀더 필요하다.

타이머는 자바스크립트에서 일정 시간 후에 함수를 실행시키는데 유용한 방법인데, setTimeout을 한번 사용하던지 setInterval을 반복적으로 사용할 수 있다. 이것들은 자바스크립트에서는 sleep 명령과 동일한 명령이 없기 때문에 특히나 유용하며 그렇기 때문에 이것들은 가장 좋은 대안을 제공한다. 이것들은 지정된 간격의 시간이 지날 때까지 어떠한 CPU 시간도 사용하지 않는다. 한가지 반드시 주의해야 할 것은 이 강력한 기능을 남용하지 말아야 하는 것인데, 적당히 사용한다면 일부 인상적인 효과를 달성할 수 있게 해준다. 이 경우에는 인자인 vis에 기초하여 Message_UpdatePos(msg, dy)를 실행시키는 타이머를 설정하며 타이머는 1ms 마다 실행된다. 전역 변수인 intr를 사용하여 타이머 포인터를 저장했음에 주의한다. 이것은 Message_Display를 몇번 호출하는 동안 유지하여야 하기 때문이다.

마지막으로 Message_UpdatePos를 보면 근본적으로 Message_Display의 처음 시작부분--메시지에 대한 핸들을 얻어내고 페이지의 상단으로부터 y 간격을 업데이트하는--과 같음에 주목하자. 그러므로 페이지가 스크롤될 때 메시지 위치는 스크롤 이벤트의 1ms 이내에 거기에 따라 재조정되고, 우상단 구석에서 항상 같은 위치에 떠있어 보인다. 메시지는 브라우저를 넓게 보거나 좁게 보기 위해 수평적으로 크기를 바꾸면 움직이지 않음에 주의한다. 연습삼아 이것이 잘 작동할 수 있게 코드를 수정해보자.
 
제공 : 한빛 네트워크
저자 : Howard Feldman
역자 : 추홍엽
원문 : Writing Advanced JavaScript
 

dojo Framework part1.

WEB2.0/ajax | 2008. 3. 6. 09:30
Posted by 시반
제 1 장  dojo 를 시작하며

 

몇년전에 ajax란 것을 듣고 사용하기 위해서 좀더 쉽게 쓸수 없을까 하는 생각에 혹 framework는 없을까

당시엔 국내에 관련서적도 없었던 터라 인터넷 검색으로 framework 라고 해서 찾은 것이 prototype 과 dojo 였다.

그때에도 ui적인 측면이 강한 dojo에 흥미를 가졌었지만 느린 속도 때문에  직관적이면서 심플한 prototype 을 애용하게 되었다.

하지만 이클립스 wtp 에서도 dojo 를 지원하더니 이번에 스트럿츠2로 한번 개발해볼까 했더니

지원하는 테마인 ajax가 바로 dojo 가 아닌가

기존에 prototype 으로 만들어논 프레임웍을 스트럿츠2의 테마로 등록하는 방법은 없을까 찾아는 보지만 어째 좀..

이번기회에 다시금 dojo에 익숙해져 보자는 생각에 끄적여본다.

 

dojo이 드뎌 1.0대로 진입을.. 0_0

예전엔 객체 생성하는 방법도 버젼마다 조금씩 달랐었는데 이번버젼엔 어떻게 바뀌었을까나

 

dojo는 홈페이지에서 받던지 다음링크 http://download.dojotoolkit.org/release-1.0.2/dojo-release-1.0.2.zip 에서 파일을 다운 받아서 웹 디렉토리에 적당히 풀고, (그 디렉토리를 js라고 하면) 다음과 같이 쓰고 사용하면 된다.

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

주의: 할 점은 dojo가 두 번 들어간다는 것이다. dojo폴더 이하에 생긴다는 뜻...

확실히 가볍던 prototype에 비해 왠지 묵진한 느낌의 dojo.  zip파일 로도 약 3.9M 정도니..묵진한건 기분만은 아닌듯

하지만 다른 건 필요없다.

기본기능에 충실한 dojo만을 사용하길 원한다면   AOL developer network 에서 지원하는 dojo framework를 사용해도 된다.

 

아니면 다음링크에서 기냥 받아두 된다.

http://o.aolcdn.com/dojo/1.0.2/dojo/dojo.xd.js.uncompressed.js (압축안된 버전)
http://o.aolcdn.com/dojo/1.0.2/dojo/dojo.xd.js(압축된 버전)

와우. dojo 가 이리 가볍다니...ㅋ

 

아니면 다음과 같이 사용해도 된다.

<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.2/dojo/dojo.xd.js"></script>

'WEB2.0 > ajax' 카테고리의 다른 글

dojo Framework part 2.유틸리티 함수  (0) 2008.03.13
Ajax와 Java EE의 통합  (0) 2006.09.02
Ajax 한글 파라미터 보내기  (0) 2006.07.13
Ajax 마스터, Part 1: Ajax 소개  (0) 2006.06.02
Prototype.js 가이드 03 참조문서  (0) 2006.05.11
 

개발자의 새로운 키, 웹2.0

WEB2.0 | 2006. 8. 25. 09:34
Posted by 시반

갑자기 웹2.0이라는 말이 홍수처럼 쏟아지고 있다. 그저 한때 스쳐지나갈 유행이라고 무시하기에는 그 물결이 너무 세차다. 저마다 자신의 일에 몰두하다 보면, 새로운 개념을 받아들이기란 쉽지가 않다. 늘 새로운 기술에 적응해야만 하는 개발자라면 웹2.0은 이미 현실로 다가왔다. 기왕 배워야 할 내용이라면 먼저 배우고, 먼저 적용하는 것이 좋다. 웹2.0에 대해 개발자들이 알아야 할 최소한의 내용에 대해서만 정리했으니 참고하도록 하자.

김중태| handal@gmail.com
서강대 국문학과를 졸업하고 현재 IT컬럼니스트와 강사로 활동 중이다. 한글운동과 글꼴 보급에 힘을 썼는데 ‘새롬데이타맨’ 등의 프로그램이나 기차역 지하철역 등의 안내화면에서 볼 수 있는 글꼴이 김중태 원장이 보급한 글꼴이다. 최근 ‘웹2.0 시대의 기회, 시맨틱웹’이라는 책을 출간하고 현재 활발한 강연 활동을 펼치고 있다. 김중태문화원(www.dal.co.kr)도 운영하고 있다.


‘웹2.0(Web 2.0)’이라는 개념이 등장하기 전까지 차세대 웹(NGWeb = Next Generation Web)을 뜻하는 말로는 시맨틱웹(Semantic Web)을 사용했다. 시맨틱웹은 웹의 창시자인 팀 버너스 리에 의해 1998년에 제안된 차세대 웹의 이름이다. 시맨틱웹의 특징은 인공지능을 통한 자동화가 강화된 웹이다. 다시 말해 최대한 사람의 손을 거치지 않고 프로그램이나 기계끼리 알아서 처리하는 웹을 시맨틱웹이라고 한 것이다.

웹2.0 다시 한번 살펴보자
웹2.0은 최근에 만들어진 개념으로 차세대 웹을 경제적인 관점에서 접근하다가 만들어진 말이다. 닷컴 버블 붕괴 이후 인터넷 기업은 아마존, 이베이, 구글처럼 살아남은 기업과 넷스케이프, 라이코스처럼 소멸된 기업으로 그 명암이 갈렸다. 자연스럽게 닷컴 버블에서 살아남은 기업과 죽은 기업의 차이점을 파악하고자 했다. 이 과정에서 웹 초창기 시절의 기업과 구분하기 위해 살아남은 기업을 가리키는 대명사가 필요했다.

이때 오라일리 미디어(O'Reilly Media)의 부사장인 데일 도허티(Dale Dougherty)가 닷컴 붕괴 이후 살아남은 회사들의 공통점과 기존의 웹에 전환점을 찍은 의미로 웹2.0을 제안했다. 이후 오라일리 미디어(O'Reilly Media, www.oreilly.com)는 2004년 10월 5일부터 일주일 동안 미국 샌프란시스코에서 ‘웹2.0 컨퍼런스(www.web2con.com)’를 개최했다. 따지고 보면 ‘웹2.0’이라는 개념이 퍼지기 시작한 것은 1년 반 정도에 불과한 셈이다.

일반적으로 IT용어는 개념을 생각하고 개념에 해당하는 낱말을 만든 사람이 대중에게 그 낱말의 뜻을 설명하게 마련이다. 하지만 웹2.0은 독특하게도 말을 만든 사람이 행사에 참석한 대중들에게 이 용어의 뜻에 대해 설명해보라는 독특한 과정을 거쳐서 완성되었다. 오라일리 미디어는 “우리가 웹2.0이라는 용어를 만들었는데, 이 낱말의 뜻에 대해 당신들이 설명해주면 좋겠습니다.”라고 화두를 던지며 여러 가지 질문을 했다. 참석자는 당황스럽긴 해도 자신이 생각하는 닷컴 버블 이전과 이후의 상황에 대해 이야기를 풀어나갔다.

참석자들은 “내가 보기에 초창기 웹에 비하면 요즘 웹은 플랫폼이 중요해진 것 같은데.” “요즘은 기계들끼리 알아서 처리하지 않나?”라며 초창기 웹에 비해 달라진 닷컴 버블 붕괴 이후의 웹에 대해 설명하기 시작했다. 당연히 사람들마다 웹2.0에 대한 정의가 달랐다. “플랫폼이 기반 환경이 되는 웹 - Richard MacManus” “컴퓨터에게 유용한 웹 - Jeff Bezos” 등과 같이 사람마다 조금씩 다른 설명이 나왔고 해석도 달랐다. 그 과정에서 점차 모습을 갖춰가면서 웹2.0의 개념이 퍼져나가기 시작한 것이다.

사람들은 초창기 웹 서비스와 요즘 웹 서비스를 먼저 대비시켰고, 이들 서비스의 차이점, 기술적 요소, 문화적 특성을 비교해가면서 웹2.0의 모습을 만들어가기 시작했다. 이런 과정을 거쳐 1년 뒤인 2005년 가을에 팀 오라일리가 ‘What Is Web 2.0(http://www.oreillynet.com/pub/a/oreilly/tim/news/2005/09/30/what-is-web-20.html)’라는 글을 통해 자신이 일 년 동안 정리한 내용을 발표했다.

팀 오라일 리가 정의한 웹2.0이 가장 완벽한 정의라고 생각할 필요는 없다. 하지만 웹2.0이라는 낱말을 만들고 이 낱말을 정의하기 위해 컨퍼런스까지 연 팀 오라일리의 생각이 웹2.0에 대한 가장 기본적이고 명확한 설명이라고 할 수 있다. 보다 상세한 웹2.0의 개념을 알고 싶다면, 팀 오라일리의 웹2.0 설명 문서를 먼저 참고하기 바란다. 팀 오라일리의 ‘What Is Web 2.0’은 우리말로 번역되어 한빛미디어에 공개되었고, ZDNet코리아에도 또 다른 한글판이 올라와있다.

(Box)---------------------------------------------------------------------------------------
‘Web 2.0이란 무엇인가’ 한빛미디어 번역본 주소
(1) http://network.hanbitbook.co.kr/view.php?bi_id=1141
(2) http://network.hanbitbook.co.kr/view.php?bi_id=1148
(3) http://network.hanbitbook.co.kr/view.php?bi_id=1152
------------------------------------------------------------------------------------------

(표)---------------------------------------------------------------------------------------
[Web 1.0]                              [Web 2.0]
DoubleClick                            Google AdSense
Ofoto                                      Flickr
Akamai                                   BitTorrent
mp3.com                                Napster
Britannica Online                    Wikipedia
personal websites                  blogging
evite                                       upcoming.org and EVDB
domain name speculation      search engine optimization
page views                             cost per click
screen scraping                      web services
publishing                               participation
content management systems      wikis
directories (taxonomy)            tagging ("folksonomy")
stickiness                                syndication
-------------------------------------------------------------------------------------------
<표 1> 팀 오라일리의 웹2.0 비교표

팀 오라일리는 ‘What Is Web 2.0’을 통해 웹2.0을 한 마디로 명확하게 정의 내리지는 못했지만, 웹2.0의 특징과 범주는 확고하게 설명하고 있다. 오라일리는 구글 애드센스, 플릭커, 냅스터, 위키피디아, 블로깅이 웹2.0의 범주에 든다고 말했다. 사람들은 웹2.0의 범주에 들어가는 서비스의 특징을 파악하기 시작했고 그 결과 ‘플랫폼으로서의 웹’ ‘협업과 참여의 웹’ ‘인간을 위한 웹’ 등으로 웹2.0을 정의하기 시작했다. 팀 오라일리는 웹2.0의 특징을 일곱 가지로 구분해 설명했다. 설명 내용이 20~30여쪽 정도로 많은 내용이다. 영문판과 한글판 주소를 참고해 읽어보기 바란다.

(Box)---------------------------------------------------------------------------------------
팀 오라일리가 설명한 웹2.0의 특징
◆ 플랫폼으로서의 웹
◆ 집단 지성(collective intelligence) 이용
◆ 다음 시대의 인텔 인사이드는 데이터
◆ 소프트웨어 릴리스 주기의 종말
◆ 가벼운 프로그래밍 모델
◆ 단일 디바이스를 넘어선 소프트웨어
◆ 풍부한 사용자 경험
-------------------------------------------------------------------------------------------
팀 오라일리는 일곱 가지 특징을 설명한 후에 웹2.0 회사들의 핵심 경쟁력 일곱 가지를 이야기하며 웹2.0에 대한 설명을 마쳤다. 웹2.0 회사의 핵심 경쟁력을 줄여서 표현하자면 ‘패키지가 아닌 확장성을 가진 소프트웨어, 데이터 통제권, 많은 사람의 참여를 이끄는 모델, 가벼운 사용자 인터페이스와 개발 모델, 유비쿼터스 시대에 맞는 소프트웨어’ 등이다. 이런 요소를 갖출 때 웹2.0 기업이 되는 것이며, 일곱 가지를 조금씩 잘 하는 것보다 한 분야에서 탁월한 것이 더 효과적이라고 설명하기도 했다.

웹2.0의 세 기둥인 RSS, tag, Ajax
웹2.0이라는 말이 나온 과정을 이해한다면 웹2.0이 거품이 아니라는 사실을 알 수 있을 것이다. 웹2.0이라는 낱말이 닷컴버블 붕괴 때 살아남은 기업을 가리키는 말이고, 웹2.0 기업인 아마존과 구글 등은 수익을 내고 있는 기업이기 때문이다. 따라서 웹2.0이 거품이냐 아니냐를 논할 시기는 지났다. 이제 논의해야 할 이야기는 웹2.0의 대표기업으로 손꼽는 아마존과 구글이 어떻게 수많은 사용자의 욕구를 만족시키면서 변화에 적응했느냐 하는 점이다. 특히 개발자라면 이들 기업이 사용한 각종 기술에 관심을 두어야 한다.

웹2.0 기업을 떠받들고 있는 기술은 다양하다. 크게 다음과 같은 기술이 웹2.0 기업을 구성하고 있는 기술적 요소라고 볼 수 있다.

(Box)---------------------------------------------------------------------------------------
웹2.0 기업의 기술적 요소
◆ Ajax 등을 이용한 사용자 편의성이 높은 인터페이스
◆ 웹표준을 지킴으로써 높은 웹접근성을 보이고 유비쿼터스 시대에 잘 적응
◆ 브라우저 호환(크로스 브라우징) 기술로 어떤 브라우저, 어떤 운영체제에서도 잘 보이는 웹
◆ 처음부터 세계 시장을 염두에 두고 유니코드(UTF-8)로 사이트를 구성
◆ 오픈 API로 시장 지배력을 강화하고 혼합(Mashup) 서비스 출현을 지원
◆ 가벼운 얼개(framework) 사용
◆ RSS와 같은 다양한 배포도구 사용
◆ 태그와 같이 사용자 참여를 이끄는 기술
-------------------------------------------------------------------------------------------------------

웹2.0 기업의 기술적 요소는 실제로는 더 복잡하지만 이상의 여덟 가지 요소만 모두 갖추고 구현해도 이전과는 확연하게 다른 사이트가 만들어질 것이다. 웹2.0을 구현하기 위해 많은 기술들이 사용되지만 현재까지 사용자들이 쉽게 받아들이는 기술은 RSS, Tag, Ajax의 세 가지 기술이다. 개발자 입장에서 보자면 하루 이틀 정도면 구현이 가능한 기술로 보일 정도이니 난이도 높은 기술이라고 말하기는 어렵다.

하지만 많은 웹 사이트가 이 세 가지 기술을 활용해 새로운 개념과 서비스를 만들어가고 있다는 사실에 주목해야 한다. 3월에 열린 NGWeb 컨퍼런스에서 아마존(Amazon.com)의 제프 바(Jeff Barr)가 말한 내용의 핵심도 “구글이 웹2.0의 표준이다. 웹2.0의 주요 기술은 RSS, Tag, Ajax다.”라는 것이다. 기술의 난이도보다 중요한 것은 사용자들이 받아들이는 기술, 세상을 변화시키는 기술인 것이다.


구독시대로 바꾸고, 개인의 힘을 강화시킨 RSS
RSS는 알맹이 배급(Content Syndication)을 위해 나온 XML 형태의 규격 중 하나로 웹 사이트끼리 서로 자료를 주고받기 위한 규격이다. A 사이트에서 RSS를 지원하면 다른 곳에서 A 사이트의 RSS 정보를 읽은 다음에 A 사이트의 자료를 활용할 수 있다. 블로그 사이트나 언론 사이트에 가면 ‘RSS, XML’ 등의 아이콘이 붙어 있는데 이런 아이콘을 누르면 RSS 주소가 표시된다.


<화면 1> 블로그라인스(www.bloglines.com)를 통해 RSS를 구독하는 모습

RSS의 역사는 복잡하다. RSS는 10년 전인 1995년의 MCF(Meta Content Framework) 프로젝트에서 출발한다. 이후 1997년 프로젝트가 종료되고 담당자인 구하(Guha)가 넷스케이프(Netscape)사로 옮겨가면서 MCF는 XML 기반으로 변화되는데 이것이 바로 RDF다. 넷스케이프사는 AOL로 넘어갔고 여기에서 RSS(RDF Site Summary)를 선보였다. 이후 넷스케이프사가 개발을 포기하면서 두 개의 그룹으로 분리되어 RSS를 개발하게 된다.

RDF 진영인 ‘RSS-DEV Working Group’이 개발하는 RSS는 2000년에 발표한 ‘RSS 1.0(RDF Site Summary 1.0)’이고, 반RDF 진영인 ‘UserLand’의 RSS는 2002년에 발표한 ‘RSS 2.0(Really Simple Syndication 2.0)’이다. 이처럼 RSS 규격이 분리되면서 표준과 방식, 소유권에 대한 논쟁이 일어났는데 아직도 이들 형식은 통일되지 않은 상태다. ‘PIE, ATOM, OPML, mbox’ 등은 RSS와 다른 새로운 배포형식 규격이다.

RSS는 많은 것을 변화시켰다. RSS는 사용자가 웹 페이지를 방문해 보는 방문시대에서 구독시대로 변화시켰다. 개발자 관점으로 보면 페이지가 변경될 때마다 변경된 사실을 알 수 있는 큰 변화가 일어난 것이다. 이런 특징 때문에 RSS를 ‘성장하는 웹(the incremental web)’ 또는 ‘살아있는 웹(live web)’이라고 불릴 정도다.

RSS 보급에는 블로그의 영향을 빼놓을 수 없다. 실질적으로 RSS를 가장 잘 활용하고 있는 곳이 블로그이기 때문이다. 신기술이 빛을 보지 못하고 사라지는 경우가 많은데 RSS는 블로그에서 적극적으로 이용되면서 빛을 보게 된 것이다. 블로그의 확산과 맞물리면서 RSS 기술도 확산되었다.

RSS는 RSS를 발행하는 사람과 이를 수집하는 쪽, 재배포하는 곳, 구독하는 사람에 따라서 다양한 평가를 받을 수 있다. 발행자 입장에서 보면 RSS는 발행자의 힘을 강화시켜 준 일등공신이다. 과거에는 ‘갑’이라는 개인이 A라는 좋은 글을 쓴다 해도 A라는 문서를 작성한 사실조차 네티즌에게 알릴 방법이 없었다. 그러나 지금은 ‘갑’이 A라는 글을 작성하는 즉시 RSS 구독자의 구독기나 메타사이트에 이 사실이 전달된다. 이 글은 구독자와 메타사이트 방문객을 통해 또 다시 재배포가 이루어지면서 순식간에 네트워크 전체에 퍼진다. 중앙에 집중되었던 배포권이 개인에게도 주어짐으로써 개인 블로그의 힘이 강화된 것이다. 블로그가 매체나 언론으로 자주 조명 받는 이유는 RSS라는 배포 기술을 활용하고 있기 때문이다.


<화면 2> 올블로그(www.allblog.net)와 같은 메타사이트를 통해 RSS를 좀 더 많은 사람에게 배포할 수 있다.

물론, RSS도 문제점은 있다. 사용법이 어려운 것이 첫 번째 문제다. RSS 주소를 복사한 다음에 구독기에 추가하는 사용법은 학습이 필요한 복잡한 방법이다. 이 때문에 파이어폭스와 같은 브라우저는 라이브북마크라는 RSS 구독 기능을 내장해, 즐겨찾기처럼 RSS 구독을 추가하도록 지원하고 있다. 하지만 더욱 좋은 방법은 사용자가 RSS라는 사실을 인식하지 못하면서 RSS를 사용하는 형태가 될 것이다. 야후나 구글 등은 사용자들에게 채널 형태로 구독할 사이트를 추천해주고 사용자가 이를 구독하겠다고 OK 단추만 누르면 해당 사이트를 RSS로 구독할 수 있게 도와준다.

RSS의 또 다른 문제는 철학적 문제다. 발행자와 구독자의 요구가 서로 다른 데서 생기는 거리를 어떻게 해결하느냐가 가장 큰 문제다. 그 외에도 RSS 수집기가 발행자 사이트에 주는 트래픽 부담이나 RSS 내 광고와 같은 기술적 문제도 해결해야 한다. RSS의 향후 과제는 새로운 기능의 구현보다는 이런 문제를 해결하는 기술 구현이 되어야 할 것이다.

검색과 분류방법의 새로운 보완책 태그
태그(tag)는 학생들의 이름표, 수하물의 딱지, 제품의 상표를 뜻한다. 웹에서도 태그 기술은 어떤 글이나 자료에 붙여놓은 추가정보를 뜻한다. 다른 말로 키워드(keyword) 기술이라 할 수 있다. 과거의 태그 기술과 달라진 점은 시맨틱웹 기술을 적용하여 ‘의미있는 꼬리표(semantic tags)’로 재탄생했다는 점이다.

태그 방식은 기존의 폴더형(디렉토리형) 분류 방식이나 낱말 중심 검색방식의 문제점을 보완해준다. 예를 들어 지메일(gmail), 피카사에 대한 글이 있어도 기존 검색방법은 ‘구글’이라는 낱말이 들어가지 않았다는 이유로 검색결과에 포함시키지 않는다. 하지만 지메일 피카사 글에 ‘구글’이라는 낱말을 태그로 달아두면 ‘구글’이라는 태그로 지메일과 피카사 글도 함께 볼 수 있다.

낱말 검색의 또 다른 문제는 불필요한 검색결과가 너무 많다는 사실이다. ‘구글’이 들어간 모든 문서를 검색해 1천 개의 문서를 보여준다고 하자. 1천 개 문서 중에서 995개는 단지 구글이라는 낱말이 나열된 것에 불과하고 구글에 관한 심층적인 글은 단 다섯 개일 것이다. 이 중 구글과 관련된 문서가 몇 개인지 알 수도 없고, 다섯 개라는 사실을 안다고 해도 어느 문서인지 찾을 수도 없다. 하지만 다섯 개의 문서에만 ‘구글’이라는 낱말을 태그로 달아두었다면 태그 찾기로 정확하게 구글 관련 주요 문서 다섯 개만 쉽게 찾을 수 있다.

태그는 단일 분류의 문제점도 해결해준다. 꽃이 핀 관악산에서 우리 가족이 토끼를 앞에 두고 찍은 사진이 있다고 해보자. 기존의 단일 분류 게시판 방식에서는 이 사진을 ‘자연-산’에 올릴 경우, ‘자연-꽃’이나 ‘동물-고양이’ ‘인물-어린이’ ‘인물-가족’ 게시판에서는 볼 수 없게 된다. 하지만 이 사진에 ‘산, 관악산, 꽃, 개나리, 동물, 토끼, 가족, 사랑, 어린이, 아들, 펜탁스...’와 같은 태그를 붙여둔다면 이 사진은 어떤 주제로도 검색이 가능하다.


<화면 3> 태그의 모양이 구름 모양처럼 들쑥날쑥 하다고 해서 붙인 이름이 꼬리표구름(tag cloud)이다.

국내에서는 태그를 개인 블로그에서 주로 도입해 사용하고 있지만 사실은 쇼핑몰을 비롯한 상업 사이트에서 더욱 유용하게 사용할 수 있는 개념이다. 예를 들어 과거에는 ‘의자’를 분류할 때 ‘가구-의자’로만 분류했지만 의자의 속성이 가구만 있는 것이 아니다. 실제로 사람들이 어떤 제품을 구입할 때는 의자부터 생각하지 않고 재료나 색깔을 먼저 고려하는 경우도 있다. 즉 ‘분홍색 계열로 집을 꾸미고 싶은데 쓸만한 물건이 있을까?’ ‘우리 가게는 금속 재질로 꾸며서 미래적인 분위기를 한 번 만들어봐야지.’라고 생각하고 쓸만한 물건을 찾는 경우가 많다. 이때 금속으로 된 물건에서 디자인이 괜찮은 금속제 의자를 보고 구입할 수도 있고, 분홍색 계열 제품 중에서 의자나 꽃병을 보고 거실에 두면 잘 어울리겠다고 생각해 구입하는 경우도 있을 것이다. 의자나 꽃병을 구입하겠다고 생각하고 구입하는 것이 아니라 거실에 어울리는 색깔의 제품을 찾다가 의자와 꽃병을 구입할 수도 있는 것이다.

따라서 의자는 ‘가구-의자’로만 분류할 것이 아니라, ‘색깔-분홍색-의자’ ‘재질-금속-의자’ ‘크기-1인용-의자’ ‘사용연령-유아용-의자’ 등으로 수도 없이 분류할 수 있을 것이다. ‘분홍색, 금속, 1인용, 유아용, 10만원대, ...’등은 모두 의자를 구성하는 속성의 하나고 이런 속성으로도 원하는 의자를 찾을 수 있어야 하는 것이다. 에트시(www.etsy.com)라는 사이트를 보면 태그를 이용해 제품을 색깔이나 재질별로도 찾을 수 있게 해준다. 에트시처럼 국내 사이트도 태그를 다양하게 적용할 필요가 있다.


<화면 4> www.etsy.com 사이트는 재질이나 색깔 별 태그를 활용한다.

태그도 해결할 문제점이 많다. 먼저 사람이 일일이 손으로 태그를 달지 않아도 되는 자동태깅시스템이 필요하다. 자동태깅시스템은 여러 가지 방법으로 구현할 수 있다. 자료에 있는 메타데이터를 활용하는 것이 하나의 사례가 될 수 있다. 사진에는 사진 촬영 시각과 노출도, 해상도, 촬영 기종 정보가 들어가는데 이런 것은 자동으로 추출해 달아줄 수 있다. 아마존이 활용하는 것처럼 사진기에 GPS를 연결하면 사진을 찍은 장소도 자동으로 넣어줄 수 있다. 태터툴즈처럼 많은 사용자들이 선택한 태그를 추천 태그로 제시해주는 추천기능을 활용하는 것도 하나의 방법이다.

작성자가 쓴 태그가 주제와 어울리지 않을 수도 있다. 작성자는 영화에 대한 글이라고 태그를 달았지만 독자는 오히려 ‘가족사랑’에 대한 이야기라고 생각할 수도 있다. 때문에 독자가 태그를 다는 방법도 고려해야 한다.

태그와 같은 폭소노미(Folksonomy, 대중분류)가 주목받는 이유는 많은 사람들이 참여할 경우 더 정확해지고 대중적 가치를 가진 정보를 찾기 편하기 때문이다. 태그는 사용자의 선택과 결정을 돕는 기술이다. 이 때문에 태터툴즈 eolin(www.eolin.com), 태그클라우드(www.tagcloud.com), 이글루스(www.egloos.com) 가든처럼 다양한 곳에서 태그를 활용하고 있다.

새로운 개념의 편리성을 제공하는 Ajax
Ajax는 ‘Asynchronous JavaScript and XML’의 줄임말로, 뜻은 ‘비동기 자바스크립트 XML’으로 구글과 야후, 아마존 등의 여러 서비스에서 Ajax 기술을 활용하고 있다. ‘Ajax’라는 낱말은 제시 제임스 가렛(Jesse James Garrett)이 2005년 2월 18일 쓴 ‘A New Approach to Web Applications’이라는 에세이에서 ‘Ajax(Asynchronous JavaScript + XML)’라는 낱말로 이 기술을 소개한 이후 퍼졌다. Ajax는 현재 ‘에이잭스’나 ‘아작스’로 표기하고 있는데, 원음에 가까운 ‘에이잭스’ 표기가 늘고 있다.

(Box)---------------------------------------------------------------------------------------
Ajax가 포함하는 기술
- XHTML과 CSS를 이용한 웹 표준 기반 구현
- Document Object Model을 사용한 동적인 화면과 상호작용
- XML과 XSLT를 이용한 자료 교환과 처리
- XMLHttpRequest를 사용한 비동기 자료 검색
- 그리고 이들 기술을 묶어주는 자바스크립트
-------------------------------------------------------------------------------------------

* 제시 제임스 가렛의 글 : http://www.adaptivepath.com/publications/essays/archives/000385.php


<화면 5> 제시 제임스 가렛이 비교한 이전의 웹 응용 모델과 Ajax 웹 응용 모델의 차이

제시 제임스 가렛은 Ajax에 대해 “여러 가지 기술이 포함되어 있으며, 각 기술로도 훌륭하지만 함께 하면 더 강력한 기술”이라고 설명했다. Ajax에 대한 비판의 목소리도 있지만 Ajax를 응용한 기술들을 보면 Ajax가 사용자의 마음을 움직이는 유용한 기술이라는 점을 부정할 수 없다.

한 예로 패닉닷컴 쇼핑몰(http://panic.com/goods/)에서 셔츠를 구입하는 과정을 보자. 마우스로 셔츠를 아래에 있는 장바구니(Shopping Cart)로 끌어다놓기만 하면 된다. 중간에 마음이 바뀌면 장바구니의 셔츠를 다시 진열대로 끌어다 놓기만 하면 된다. 학습이 줄고 사용성이 강화되는 웹2.0의 인터페이스가 무엇인지 쉽게 알 수 있다.

구글 지도(http://maps.google.com/)를 보면 웹표준을 최대한 따르면서 Ajax로 구현하고 있다. 이 때문에 구글 지도는 대부분의 브라우저에서 별도의 플러그인 프로그램을 깔지 않고 사용한다. PC용 브라우저는 물론이고 휴대전화, 휴대용게임기, PDA, 냉장고와 같은 유비쿼터스 시대의 모든 기기에서 구글 지도를 사용할 수 있다는 뜻이다. PC에서조차 별도의 플러그인을 깔아야 하는 국내 지도 서비스와 다른 점이 여기에 있다.

구글 지도는 좋은 기술로 끝나지 않는다. 구글 지도의 위성사진을 선택하면 가보지 않은 지역이라도 집 주변이 공장지대인지, 유흥가인지, 아이가 학교에 가기 위해 횡단보도를 몇 번이나 건너야 하는지, 학교까지의 거리는 얼마나 되는지 알 수 있다. 따라서 우리나라에서는 “방 나왔어요. 보러 오세요.”라고 연락이 오면 조퇴를 하고 방을 보러 가지만, 미국에서는 구글 지도를 이용해 집에서 초등학교까지 거리가 멀다고 말하면서 몇 번지 주변의 방을 구해달라고 구체적으로 위치를 지정해 말할 수 있다. 즉 부동산문화가 바뀌는 것이고, 유통문화가 바뀌는 엄청난 변화가 일어나는 것이다. 이처럼 기획자나 개발자는 기술 외에도 기술로 인한 문화적 변화까지 예측할 수 있어야 한다.


<화면 6> 위성사진과 결합된 하이브리드 메뉴를 이용하면 해당 지역에 가지 않고도 집 주변 환경을 알 수 있다.

구글 개인화 홈페이지(http://www.google.co.kr/ig)에서는 마우스를 이용해 단락을 손쉽게 옮길 수 있는 기능을 지원한다. 이 기술이 우리에게 시사하는 것은 서버에서 보내준 화면은 고정된다는 HTML 문서에 대한 고정관념을 깬 점이다.

구글은 이미 불러온 화면도 좌우를 바꿀 수 있다는 새로운 발상의 전환을 보여주고 있다. PDA 등으로 네이버 뉴스를 보면 오른쪽에 있는 ‘오늘의 주요뉴스’가 안 보여 답답하다. Ajax 기술을 이용한다면 오른쪽의 ‘오늘의 주요뉴스’를 왼쪽으로 옮기고, 왼쪽의 뉴스 본문을 오른쪽으로 이동시켜 네이버뉴스를 사용할 수도 있다. 별도의 모바일용 웹페이지를 만들어야 하는 것이 아니라 사용자가 페이지를 재구성할 수 있도록 설계하면 되는 일이다.

웹2.0 시대에 필요한 것은 철학과 실천
간략하게 소개했지만 웹2.0을 구성하는 기술은 훨씬 다양하다. 배우려는 마음만 먹는다면 웹에 있는 수많은 문서를 통해 웹2.0을 공부할 수 있다. 하지만 기술 익힘보다 철학 만들기가 더 중요하다. 나는 ‘웹2.0 기술을 어떻게 이용하면 돈을 벌 수 있을까?’를 생각하기보다는 ‘사람들이 좀 더 편리하고 행복해할 수 있는 서비스가 무엇일까?’를 먼저 고민하라고 말한다. 그 다음에 그 서비스가 돈이 될지를 고민해야 하는 것이다. 철학은 기술을 만들고 기술은 문화를 만든다. 행복한 철학은 행복한 기술과 문화를 만든다는 사실을 잊어서는 안 된다.

야후의 제리양이 성공할 수 있었던 이유는 뛰어난 기술이 아니라 좋은 철학을 가지고 있었기 때문이다. 제리양이 공개한 즐겨찾기 목록은 웹을 아는 사람이라면 누구나 만들 수 있는 HTML 문서에 불과했다. 그러나 제리양은 자신의 즐겨찾기 목록을 공개했고, 이 목록을 유용하게 사용하는 많은 사람들이 더욱 많은 사이트를 알려주었다. 이렇게 제리양의 즐겨찾기 목록에 추가된 사이트가 늘면서 한 눈에 보기 어렵게 되자 디렉토리 분류 기술이 필요해졌고 검색 기술이 필요해졌다. 공개와 공유 정신, 참여와 협업이 야후의 성공으로 이어진 것이다.

야후도 블로그 프로그램인 태터툴즈도 메타사이트인 올블로그도 며칠이면 뚝딱뚝딱 만들 수 있다. 많은 이들이 “나는 올블로그 같은 메타사이트는 하루면 만들 수 있어”라고 말한다. 하지만 오늘 우리가 알고 있는 낱말은 야후와 태터툴즈, 올블로그다. 태터툴즈나 올블로그를 만든 개발자가 국내 개발자 중에서 가장 뛰어난 실력을 가진 것은 아니다. 하지만 그들은 ‘실제로 실천했기에 위대한’ 것이다. 백 마디 말보다 하나의 실천이 중요한 것은 예나 지금이나 변함없는 진리인 것이다.


<화면 7> 한 사람의 작은 실천이 태터앤컴퍼니라는 기업으로 발전했다.

웹2.0의 구성 요소가 새로운 것은 아닐지라도 웹2.0은 새로운 생각의 기회, 더 적은 돈으로 아이디어를 구현할 기회를 제공한다는 사실을 플릭커나 델리셔스, 블로그라인스를 비롯한 수 천 개의 웹2.0 신생기업이 보여주고 있다. 수 천 개의 신생 웹2.0 기업이 모두 성공할 수는 없겠지만 웹2.0이라는 낱말이 새로운 생각의 기회, 새로운 실천의 기회를 제공하고 있다는 사실만으로도 관심을 가지고 공부할 가치는 있다. 백 가지 생각으로는 세상을 바꾸지 못하지만 하나의 실천은 세상을 바꿀 수도 있다.

 

출처:마소

 

HTML의 미래, Part 1: WHATWG

WEB2.0 | 2006. 6. 2. 09:26
Posted by 시반

HTML을 향상시킨 Web Hypertext Application Technology Working Group만의 접근 방식

 

Edd Dumbill, 회장, XTech Conference

2005 년 12 월 06 일

웹 작성자, 브라우저 개발자, 표준 기구가 제안하는 HTML의 다양한 방식들을 검토한다. 이 글에서는 WHATWG 스팩으로 구체화된 점증적인 접근방식과 W3C에서 제안한 XHTML을 다룬다. 또한, W3C의 새로운 Rich Client Activity도 설명한다. Part 1에서는 WHATWG에서 개발한 두 개의 스팩인 Web Applications 1.0(HTML5)과 Web Forms 2.0에 초점을 맞춘다.

HTML은 웹 페이지를 만드는데 있어서 그렇게 좋은 언어는 아니다. 하지만 웹을 만들기에는 매우 좋은 언어이다.

HTML은 배우기 쉽다는 점과 브라우저의 소스 보기 기능 때문에 웹은 대중성을 확보할 수 있었다. World Wide Web Consortium(W3C)은 HTML을 표준화 하는데 앞장서서 웹 브라우저가 같은 언어를 구현하도록 했다. CSS의 출현과 표준 기반의 웹 디자인의 동반 성장은 HTML 혼란을 종식시키고 사용자와 개발자에게 더 나은 웹을 경험할 수 있도록 하였다.

이는 대부분 여러분들도 알고 있는 사실이다. 결과적으로 웹은 여러분의 삶과 비즈니스에 긍정적인 영향을 주었다. 하지만 HTML은 그렇게 좋은 언어는 아니라는 사실은 여전하다. 왜 HTML은 H1 에서 H6 까지 헤딩을 갖고 있어야 하는가? 여섯 레벨이나 되는 헤딩 계층을 누가 그렇게 심각하게 고려하겠는가? 그리고 3D 그래픽 카드와 세련된 사용자 인터페이스가 나와있는 이 시점에 웹 페이지들이 고리타분한 텍스트 박스와 라디오 버튼으로만 제한될 이유가 없다.

웹 퍼블리싱과 웹 애플리케이션들이 현대적인 사용자 인터페이스의 많은 기술들을 사용할 수 있도록, 다양한 그룹들이 HTML을 개발하고 있다는 것은 당연한 수순이다. 이들은 크게 세 개의 그룹으로 나뉜다. 첫 번째는 오늘날의 기술을 사용하는 사람들이다. 이것은 Asynchronous JavaScript and XML(Ajax)가 지향하는 바이기도 하다. JavaScript와 브라우저의 XMLHttpRequest 객체를 사용하여 동적 사용자 인터페이스를 만든다. 결과는 놀라울 수 있지만 표준 방식이 아니다.

다른 두 개의 그룹들은 앞으로의 향상에 초점을 맞추고 있다. W3C는 데스크탑 브라우저 제조자들에 국한되지 않고 광범위한 벤더들의 요구 사항들에 근거하여 XHTML 2.0을 개발하고 있다. XHTML 2.0은 급진적인 단계로 보여진다. 반면, Web Hypertext Application Technology Working Group(WHATWG)는 점증적인 스팩 세트를 추진하고 있다. 가장 필요한 기능부터 브라우저에 추가하여 HTML을 진화하는 것이다. WHATWG의 몇몇 기능들은 Apple의 Safari 브라우저와 Mozilla Firefox 1.5에 이미 구현되어 있다.(참고자료)

이 글에서는 W3C와 WHATWG가 어떤 작업들을 하고 있는지를 보게 될 것이다. Ajax에 대해서는 developerWorks(참고자료)에서 많이 다루고 있다. HTML을 W3C로 가져오는데 있어서 아직까지는 표준을 둘러싼 충돌은 없지만 그렇다고 해서 두 조직들이 모든 합의에 이른 것은 아니다. 이 두 가지 접근 방식을 평가해 보려고 한다.

WHATWG, HTML 5, Web Forms 2.0

WHATWG는 "World Wide Web을 통해 애플리케이션을 작성 및 전개할 수 있는 새로운 기술을 개발하고자 하는 웹 브라우저 제조자와 관련 당사자들의 비공식적인 협업이다." WHATWG의 핵심은 브라우저(browsers(Mozilla, Opera))를 만드는 것이고, 향상의 초점은 웹 애플리케이션(applications)을 만드는 것이다.

WHATWG의 대표 스팩은 HTML5 이지만 Web Applications 1.0(참고자료)으로도 알려져 있다. HTML5는 현재 HTML 표준인 HTML 4.01과 백워드 호환성을 유지하려고 하며 HTML의 XML 버전인 XHTML 1.0과도 호환성을 유지하려고 한다. 이 스팩은 HTML과 XHTML 계열의 W3C HTML을 지원하고 있다.

HTML5외에도 Web Forms 2.0 스팩(참고자료)은 현재의 HTML 형식에서 개발자들이 느끼는 성가신 부분들을 다룬다. 최근에는 밸리데이션과 풍부한 위젯 같은 일반적인 데스크탑 애플리케이션에서 많은 기본 기능들을 생략하고 있다.

그렇다면 HTML5에 무엇이 있는가? 간단히 말해서, 아주 많다. Web Applications 1.0 스팩은 진화하고 있고 그 무엇보다도 완벽하게 개발되고 있다. 다음은 새로운 기능들이다.

  • 캘린더 컨트롤, 어드레스 카드, 데이터그리드, 게이지 및 프로그레스 미터, 드래그 앤 드롭, 메뉴 등의 새로운 레이아웃 엘리먼트들.
  • 서버에서 전송된 DOM 이벤트 및 Document Object Model(DOM)으로의 프로그래밍 확장.
  • Ajax 통신의 중심인 표준 XMLHttpRequest 객체의 공식화.
  • canvas 엘리먼트를 통한 동적 비트맵 그래픽

오늘날 웹 상에 JavaScript와 함께 일회성으로서 구현된 기능들 중에서 위 기능들을 볼 수 있다. 사실 Ajax 툴킷의 최근 성장은 게이지, 캘린더 같은 위젯이 증가하는데 기여했다.




canvas

 

HTML5 기능의 전통적인 구현(웹 브라우저의 일부)은 앞서 언급했던 몇 가지의 기술들로 국한된다. 이들 중 가장 잘 알려진 것이 canvas 엘리먼트이다. Firefox 1.5와 Apple의 Safari 브라우저 역시 canvas를 구현했다.

W3C의 Scalable Vector Graphics(SVG)가 인-브라우저(in-browser) 일러스트레이션을 보여주는 방식을 제공하지만, canvas는 다른 접근 방식을 취한다. SVG 처럼 선언적 문서를 구현하는 대신 JavaScript가 그릴 수 있도록 빈 공백을 제공한다. 이러한 그래픽 모델은 선언적 웹 보다는 OpenGL 스타일에서 기인한다.

그림 1canvas 데모의 스크린샷이다.(참고자료) 사용자가 마우스를 도형 위에 갖다 대면 도형들은 서서히 커진다. 무엇보다도 이 데모는 사용자 인터페이스—그리기, 사용자 인풋 이벤트, 타이머—를 구현하는 모든 필수 요소들을 다 갖추고 있다는 것을 증명하고 있다.


그림 1. 인터랙티브 canvas 데모의 스크린샷

canvas 애플리케이션들은 이미 간단한 3D 작동의 구현으로 canvas 뚜렷한 목표(게임)에 한 단계 더 가까이 갔다.(그림 2, 참고자료)


그림 2. 간단한 게임의 스크린 샷

canvas를 프로그래밍하는 방법을 간단한 코드를 통해 설명하겠다. Listing 1이 코드표이고 결과는 그림 3에 나타나 있다.


Listing 1. 간단한 canvas 예제

<html>

  <head>

   <title>Canvas demo</title>

   <script type="text/javascript">

     function draw () {

        var canvas = document.getElementById ('hello');

        if (canvas.getContext) {

           var ctx = canvas.getContext('2d');

           ctx.fillRect (25, 25, 50, 50);

        }

     }

    </script>

    <style type="text/css">

      canvas { border: 2px solid red; }

    </style>

  </head>

  <body onload="draw ();">

    <canvas id="hello" width="100" height="100">

    </canvas>

  </body>

</html>



그림 3. Listing 1의 아웃풋

canvas가 선언적인 문법을 나타내지 않기 때문에 사용자 인터페이스 구현 영역에 더 많은 애플리케이션을 가질 수 있을 것이다. canvas의 매력은 새로운 브라우저 인터페이스 엘리먼트와 기능을 위한 프로토타이핑 기반이라는 점이다. 최고의 예제는 아마도 canvas를 사용한 SVG의 Antoine Quint의 구현일 것이다.(참고자료) Quint의 메소드를 사용하여 임베디드 SVG로 HTML 파일을 렌더링하려면 JavaScript SVG 렌더러를 반입하는 두 줄을 추가한다. 그림 4는 이 방식을 사용하여 렌더링 된 호랑이 이미지이다.


그림 4. JavaScript와 canvas 엘리먼트를 사용하여 렌더링 된 SVG 호랑이 이미지

주류 웹 설정에 있어 canvas의 유용성 여부는 시간이 말해 줄 것이다. 이것의 기능은 자바 애플릿들의 기능과 닮아있지만, JavaScript 인터페이스로는 다른 브라우저 엘리먼트를 더욱 쉽게 사용하고 인터페이싱 할 수 있다.




Web Forms 2.0

 

WHATWG 형식 스팩의 버전 넘버는 HTML4의 형식의 스팩의 기반 하에 구현하고자 하는 의도를 나타낸다. Web Applications(HTML5) 스팩과는 달리 성숙한 상태에 와있다. Web Forms 2.0은 브라우저에서 사용할 수 있는 형식 위젯들을 향상시키는 것에 초점이 맞춰져 있다.

이 새로운 형식에는 무엇이 추가되었을까?

  • 형식이 제출되기 전에 밸리데이션 구조체로 브라우저가 더 많은 체킹을 수행할 수 있다. 새로운 애트리뷰트로는 required, min, max 등이 있다.
  • 형식 엘리먼트용 validity 애트리뷰트를 이용한 타당성검사 지원과 새로운 invalid 이벤트.
  • 형식 엘리먼트용 자동 완성 제어. 브라우저가 필드 값을 기억하고 이를 자동 완성하도록 제공하는지의 여부를 문서 작성자가 가리킬 수 있도록 함. 사전 정의된 값들은 list 애트리뷰트로 전달될 수 있다.
  • 문서가 로딩될 때 형식 엘리먼트가 인풋 포커스를 받는지를 가리키는 autofocus 애트리뷰트.
  • 텍스트-홀딩 형식 엘리먼트용 언어 인풋 모드를 알려주는 inputmode 애트리뷰트
  • 파일 업로드 제어 향상. 예상 파일 유형 지정 및 파일 크기 제한 등.
  • 형식 엘리먼트 템플릿의 반복.
  • 새로운 유형의 인풋 제어: datetime, number, range, email, url. 인풋 값을 제한하기 위한 패턴의 추가.

Web Forms는 HTML5 보다 일관성 있는 스팩이고 이미 몇몇 구현에서 찾아볼 수 있다.

  • Opera 9의 베타 릴리스에는 Web Forms 2.0 지원이 포함된다.
  • 오픈 소스 Web Forms 프로젝트는 인터넷 익스플로러를 위한 DHTML+Behaviors 구현이 있다.

W3C의 차세대 형식은 XForms이다.(참고자료) XForms는 XML 문서들을 전달하는 것에 기반하여 새로운 모델의 브라우저-서버 인터랙션을 구현한다는 점이 Web Forms 2.0과는 다르다. 반대로 Web Forms 2.0은 현재의 브라우저 형식을 보다 가용성을 갖추도록 기존 형식 모델을 점증적으로 향상시킨 것이다. 이 두 스팩은 다른 필요를 채우고 있다. 하지만 몇 가지 공통점도 있다.

이 스팩은 기존의 광범위하게 구현된 형식 모델에 최소한의 영향만 주면서 XForms의 몇 가지 기능들을 추가하고자 한다. 백워드 호환성, 작성의 용이성, 쉬운 구현 등이 바로 그것이다.



기타 구현들

 

canvas는 브라우저 구현을 갖춘 주요 WHATWG 기능이다. HTML5의 나머지 부분은 아직 초기 단계에 있고 완전하게는 구현되지 않았다.

하지만 Web Applications와 Web Forms 스팩들은 새로운 중요성을 띄고 있다. 최근에 웹 애플리케이션을 위한 사용자 인터페이스 툴킷을 개발하기 위한 여러 프로젝트가 생겨났다. 이러한 구현들은 HTML과 JavaScript 기술 또는 Flash를 사용한다. 이들 중 많은 부분이 바퀴를 다시 만드는 것은 무의미하다라는 분명한 입장을 취하고 있고 WHATWG 스팩들을 통해 형식 구현을 표준화하려고 하고 있다.




결론

 

Web Forms 2.0 스팩은 분명한 필요와 스팩의 완벽성 덕택에 구현을 받아들이고 표준으로 나갈 수 있는 좋은 기회를 가졌다. 실제로 Web Forms 2.0은 W3C에 제출되었다.

하지만 HTML의 미래를 WHATWG 스팩 혼자서 감당하기는 힘들다. 어떤 부분은 단순한 혁신(XMLHttpRequest, canvas)을 의미하고, 어떤 것은 모호하고 힘이 부족하다. 게다가 HTML5의 동기는 데스크탑, 애플리케이션 중심의 사용에 맞춰져 있다. 많은 HTML들은 비 PC 장치에서 찾아 볼 수 있고, 이것 역시 방향성이 필요하다.

HTML5에서 정의된 몇몇 아이디어들은 Ajax 기반의 브라우저 인터페이스 툴킷의 등장으로 인해 구식이 되어버렸다. 개발자들은 확장성 있는 툴킷을 사용할 수 있는데 굳이 제한된 툴을 사용하려 들지 않는다. 더 풍부한 웹 인터페이스들이 위원회 보다는 시장에 의해 표준화 되어야 한다.

canvasXMLHttpRequest 같이 일반적으로 구현되었으나 아직 표준화가 되지 않은 기술들의 진보를 볼 수 있어서 기쁘다. 이러한 중요한 기능들의 상호운용성이 향상되기를 기대해 본다. 브라우저 기술을 향상시키려면 HTML5는 더욱 명확해져야 하고 현재 사용할 수 있는 것(available now), 곧 사용할 수 있는 것(available soon), 앞으로의 기능(imagineering features)들 같이 세 가지 스팩으로 나뉘어져서 효과를 얻을 수 있다.




참고자료

교육

제품 및 기술 얻기



필자소개

Edd Dumbill, 회장, XTech Conference

 

 

출처 :

한국 developerWorks  >  XML | 웹 아키텍쳐  >

 

Prototype.js 가이드 03 참조문서

WEB2.0/ajax | 2006. 5. 11. 09:35
Posted by 시반

JavaScript 클래스에 대한 확장

prototype.js라이브러리에 기능을 추가하기 위한 방법중 하나는 현재 존재하는 JavaScript클래스를 확장하는 것이다.

Object 클래스를 위한 확장

메소드 종류 인자 상세설명

extend
(destination, source)

static

destination: 객체,
source: 객체

source에서 destination으로 모든 프라퍼티와 메소드를 복사하여 상속을 구현하기 위한 방법을 제공

inspect(targetObj) static targetObj: 객체

targetObj의 사람이 읽을수 있는 문자열 표현으로 반환. 주어진 객체가 inspect 인스턴스 메소드를 정의하지 않는다면, toString 의 값을 반환

 

Number 클래스를 위한 확장

메소드 종류 인자 상세설명
toColorPart() instance (none)

숫자의 16진법 표현을 반환. 색상의 RGB컴포넌트를 HTML표현으로 변환할때 유용

succ() instance (none)

다음 숫자를 반환. 이 함수는 반복을 포함하는 시나리오에서 사용된다.

times(iterator) instance

iterator: Function(value, index)를 충족하는 함수 객체

인자 valueindex를 반복적으로 전달하는 iterator 함수를 호출하는 것은 iteration과 현재 index내 현재 값을 각각 포함한다.

다음의 예제는 0에서 9까지의 메시지 박스를 표시할것이다.

<script>
  function demoTimes(){
       var n = 10;
       n.times(
          function(value, index){
              alert(index);
         });
      /***************************
       * you could have also used:
       * (10).times( .... );
       ***************************/
}
</script>
 <input type=button value="Test Number.times()" onclick="demoTimes()">


Function 클래스를 위한 확장

메소드 종류 인자 상세설명
bind(object) instance

object: 메소드를 소유하는 객체

함수(=메소드) 소유자 객체로 미리 묶는 함수의 인스턴스를 반환. 반환된 함수는 원래의 것과 같은 인자를 가질것이다.

bindAsEventListener(object)

instance

object: 메소드를 소유하는 객체

유하는 객체 함수(=메소드) 소유자 객체로 미리 묶는 함수의 인스턴스를 반환. 반환된 함수는 이것의 인자로 현재 이벤트 객체를 가질것이다.

실제로 이 확장중 하나를 보자.

<input type=checkbox id=myChk value=1> Test?
<script>
//declaring the class
var CheckboxWatcher = Class.create();
//defining the rest of the class implmentation
CheckboxWatcher.prototype = {
   initialize: function(chkBox, message) {
                               this.chkBox = $(chkBox); this.message = message;
                               //assigning our method to the event
                               this.chkBox.onclick = this.showMessage.bindAsEventListener(this);
                 },
   showMessage: function(evt) {
                                alert(this.message + ' (' + evt.type + ')');
                           }
}; 
var watcher = new CheckboxWatcher('myChk', 'Changed');
</script>

String 클래스를 위한 확장

메소드 종류 인자 상세설명
stripTags() instance (none) HTML이나 XML태그가 삭제된 문자열을 반환
stripScripts() instance (none) 삭제된 <script /> 블럭을 가진 문자열을 반환
escapeHTML() instance (none) HTML마크업 문자들이 escaped된 문자열 반환
unescapeHTML() instance (none) escapeHTML()의 반대
extractScripts() instance (none) 문자열내에서 발견되는 모든 <script />블럭을 포함하는 Array객체 반환
evalScripts() instance (none) 문자열내에서 발견되는 각각의 <script />블럭을 평가하기
toQueryParams() instance (none)

쿼리문자열(querystring)을 파라미터 이름에 의해 인덱스화되는 결합된 Array로 쪼개기

parseQuery() instance (none) toQueryParams()와 같음.
toArray() instance (none) 문자열을 이것의 문자들의 Array로 쪼개기
camelize() instance (none)

-(하이픈)으로 분리된 문자열을 camelCaseString으로 변환하기. 이 함수는 예를 들면, 프라퍼티 스타일을 다루는 코드를 작성할때 유용하다.

Array 클래스를 위한 확장

시작하기 위해, ArrayEnumerable를 확장한다. 그래서 Enumerable객체내에 정의되는 모든 편리한 메소드는 사용가능하다. 이것외에도, 아래의 메소드들이 구현되었다.

메소드 종류 인자 상세설명
clear() instance (none) 배열을 비우고 자체를 반환한다.
first() instance (none) 배열의 첫번째 요소를 반환한다.
last() instance (none) 배열의 마지막 요소를 반환한다.
compact() instance (none) null 이거나 undefined인 요소를 제외하고 배열을 반환한다. 이 메소드는 배열자체를 변경하지 않는다.
flatten() instance (none) 기복이 없고, 1차원의 배열을 반환한다. 이 함수는 배열이고 반환된 배열내 요소를 포함하는 배열의 각 요소를 찾음으로써 수행된다.

without(value1 [, value2 [, .. valueN]])

instance

value1 ... valueN:
 배열내 존재한다면 제외될 값

인자로 주어진 요소를 제외한 배열을 반환
indexOf(value) instance

value:

 당신이 찾는 것

배열에서 찾아진다면 주어진 value의 0부터 시작하는 인덱스의 위치를 반환. value이 없다면 -1을 반환
reverse([applyToSelf]) instance

applyToSelf: 배열 자체가 반전되는지 표시

역순서로 배열을 반환. 인자가 주어지지 않거나 인자가 true라면, 배열자체는 반전될것이다. 그렇지 않으면 변경되지 않고 남는다.
shift() instance (none) 첫번째 요소를 반환하고 배열로부터 이것을 제거한다. 배열의 길이는 1 감소한다.
inspect() instance (none) 요소를 가진 배열의 잘 포맷팅된 문자열 표시를 반환하기 위해 변경

document DOM 객체를 위한 확장

메소드 종류 인자 상세설명

getElementsByClassName(className [, parentElement])

instance

className: 요소와 연관된 CSS클래스 이름,
parentElement: 객체 또는 가져올 요소를 포함하는 요소의 id.

주어진 CSS클래스명과 연관된 모든 요소를 반환. parentElement id가 주어졌다면, 전체 문서가 검색될것이다.

Event 객체를 위한 확장

프라퍼티 타입 상세설명
KEY_BACKSPACE Number 8: 되돌리기(<-) 키를 위한 상수 코드.
KEY_TAB Number 9: 탭키를 위한 상수코드
KEY_RETURN Number 13: 리턴키를 위한 상수코드
KEY_ESC Number 27: Esc키를 위한 상수코드
KEY_LEFT Number 37: 왼쪽 화살표 키를 위한 상수코드
KEY_UP Number 38: 위쪽 화살표 키를 위한 상수코드
KEY_RIGHT Number 39: 오른쪽 화살표 키를 위한 상수코드
KEY_DOWN Number 40: 아래쪽 화살표 키를 위한 상수코드
KEY_DELETE Number 46: Delete키를 위한 상수코드
observers: Array 캐시된 관찰자(observers)의 목록. 상세한 객체의 내부구현의 일부

 

메소드 종류 인자 상세설명
element(event) static event: 이벤트 객체 이벤트를 일으키는 요소를 반환
isLeftClick(event) static event: 이벤트 객체 마우스 왼쪽 버튼을 클릭시 true값 반환
pointerX(event) static event: 이벤트 객체 페이지에서 마우스 포인터의 x측 좌표값 반환
pointerY(event) static event: 이벤트 객체 페이지에서 마우스 포인터의 y측 좌표값 반환
stop(event) static event: 이벤트 객체 이벤트의 디폴트 행위를 취소하고 위임을 연기하기 위해 이 함수를 사용
findElement(event, tagName) static

event: 이벤트 객체,
tagName: 원하는 태그명

DOM트리 위쪽으로 가로지른다. 주어진 태그명을 가진 첫번째 요소를 검색한다. 이벤트를 발생시키는 요소로부터 시작한다.
observe(element, name, observer, useCapture) static

element: 객체 또는 아이디,
name: 이벤트 명 (like 'click', 'load', etc), observer: function to handle the event,
useCapture: if true, handles the event in the capture phase and if false in the bubbling phase.

이벤트를 위한 이벤트 핸들러 함수를 추가
stopObserving(element, name, observer, useCapture) static element: 객체 또는 아이디,
name: 이벤트 명 ('click' 처럼), observer: 이벤트를 다루는 함수, useCapture: true라면 capture내 이벤트를 다루고, false라면 bubbling내에서 다룬다.
이벤트로부터 이벤트 핸들러를 제거
_observeAndCache(element, name, observer, useCapture) static   private메소드, 이것에 대해 걱정하지말라.
unloadCache() static (none) private메소드, 이것에 대해 걱정하지말라. 메모리로부터 캐시된 모든 관찰자(observer)를 지운다.

window객체의 이벤트를 로그하기 위한 이벤트 핸들러를 추가하는 객체를 사용하는 방법을 보자.

<script> Event.observe(window, 'load', showMessage, false); function showMessage() { alert('Page loaded.'); } </script>

prototype.js에 새롭게 정의된 객체와 클래스

라이브러리가 당신을 돕는 다른 방법은 객체지향 디자인과 공통적인 기능을 위한 지원 모두를 구현하는 많은 객체를 제공하는 것이다.

PeriodicalExecuter 객체

이 객체는 주어진 함수를 주어진 시간간격으로 반복적으로 호출하기 위한 로직을 제공한다.

 

메소드 종류 인자 상세설명
[ctor](callback, interval) constructor callback: 파라미터 성격이 아닌 함수, interval: 초단위 시간간격 함수를 반복적으로 호출할 이 객체의 하나의 인스턴스를 생성

 

프라퍼티 타입 상세설명
callback Function() 호출되기 위한 함수. 이 함수로 전달될 파라미터는 없다.
frequency Number 이것은 수초내 간격으로 실질적으로 작용
currentlyExecuting Boolean 만약 함수 호출이 진행중이라면 표시

Prototype 객체

Prototype 객체는 사용되는 라이브러리의 버전을 명시하는 것보다 중요한 역활을 가지지 않는다.

프라퍼티 타입 상세설명
Version String 라이브러리의 버전
emptyFunction Function() 비어있는(empty) 함수 객체
K Function(obj) 주어진 파라미터를 되돌리는 함수 객체

Enumerable 객체

Enumerable 객체는 list형태의 구조내에서 항목을 반복하기 위한 좀더 멋진 코드를 작성하는 것을 허용한다.

많은 객체들은 유용한 인터페이스에 영향을 끼치기 위해 Enumerable 을 확장한다.

 

프라퍼티 타입 상세설명
Version String 라이브러리의 버전

 

메소드 종류 인자 상세설명
each(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 주어진 iterator함수를 호출하는 것은 첫번째 인자내 목록으로 각각의 요소와 두번째 인자내 요소의 인덱스 전달한다.
all([iterator]) instance iterator: Function(value, index)를 충족하는 함수 객체 이 함수는 주어진 함수를 사용하여 값들의 전체 집합을 테스트하기 위한 방법이다. iterator 함수가 어떤 요소를 위해 falsenull을 반환한다면, all은 false를 반환할것이다. 그렇지 않다면 true를 반환할것이다. iterator가 주어지지 않는다면, 요소 자체가 falsenull이 아닌지 테스트할것이다. 당신은 "모든 요소가 false가 아닌지 체크한다"와 같이 이것을 읽을수 있다.
any(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체(선택사항) 이 함수는 주어진 함수를 사용하여 값들의 전체 집합을 테스트하기 위한 방법이다. iterator함수가 어떤 요소를 위해 falsenull을 반환하지 않는다면 anytrue를 반환할것이다. 그렇지 않다면 false를 반환할것이다. iterator가 주어지지 않는다면, 요소 자체가 falsenull이 아닌지 테스트할것이다. 당신은 "어느 요소가 false가 아닌지 체크한다"와 같이 이것을 읽을수 있다.
collect(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 각각의 요소를 위한 iterator함수를 호출하고 Array로 각각의 결과를 반환한다. 집합내 각각의 요소를 위한 하나의 결과 요소는 같은 순서이다.
detect(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 각각의 요소를 위한 iterator함수를 호출하고 true를 반환하는 iterator함수를 야기하는 첫번째 요소를 반환한다. true를 반환하는 요소가 없다면, detect는 null을 반환한다.
entries() instance (none) toArray()와 같다.
find(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 detect()와 같다.
findAll(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 각각의 요소를 위한 iterator함수를 호출하고 true로 해석되는 값을 반환하는 iterator함수를 야기하는 모든 요소를 가진 Array을 반환한다. 이 함수는 reject()와는 반대의 함수이다.
grep(pattern [, iterator]) instance pattern: 요소를 일치시키기 위해 사용되는 RegExp객체, iterator: Function(value, index)를 충족하는 함수 객체 집합내 각각의 요소의 문자열 값을 pattern 정규표현식에 대해 테스트한다. 함수는 정규표현식에 대응되는 모든 요소를 포함하는 Array 를 반환할것이다. iterator함수가 주어진다면, Array는 대응되는 각각의 요소를 가진 iterator를 호출한 결과를 포함할것이다.
include(obj) instance obj: 객체 집합내 주어진 객체를 찾도록 시도한다. 객체가 찾아진다면, true를 반환하고 찾지 못한다면 false를 반환한다.
inject(initialValue, iterator) instance initialValue: 초기화 값처럼 사용되는 객체, iterator: Function(accumulator, value, index)를 충족하는 함수 객체 iterator함수를 사용하여 집합의 모든 요소를 조합한다. 호출된 iterator는 accumulator인자에서 이전 반복의 결과를 전달한다. 첫번째 반복은 accumulator인자내 initialValue를 가진다. 마지막 결과는 마지막 반환값이다.
invoke(methodName [, arg1 [, arg2 [...]]]) instance methodName: 각각의 요소내에서 호출될 메소드의 이름, arg1..argN: 메소드 호출로 전달될 인자. 집합의 각각의 요소내 methodName에 의해 명시되는 메소드를 호출하는 것은 주어진 인자(arg1에서 argN) 전달하고 Array객체로 결과를 반환한다.
map(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 collect()과 같다.
max([iterator]) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 가장 큰 값이나 iterator가 주어진다면 집합내 각각의 요소를 위한 iterator호출의 가장 큰 결과를 반환한다.
include(obj) instance obj: 객체 include()과 같다.
min([iterator]) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 가장 작은 값을 가진 요소나 iterator가 주어진다면 집합내 각각의 요소를 위한 iterator호출의 가장 작은 결과를 가진 요소를 반환한다.
partition([iterator]) instance iterator: Function(value, index)를 충족하는 함수 객체 두개의 다른 배열을 포함하는 Array를 반환한다. 첫번째 배열은 true를 반환하는 iterator함수를 야기하는 모든 요소를 포함할것이고 두번째 배열은 남아있는 요소를 포함할것이다. 만약 iterator가 주어지지 않는다면, 첫번째 배열은 true로 해석하는 요소를 포함할것이고 다른 배열은 남아있는 요소를 포함할것이다.
pluck(propertyName) instance propertyName : 각각의 요소로부터 읽어들이는 프라퍼티의 이름. 이것은 요소의 인덱스를 포함할수 있다. 집합의 각각의 요소내 propertyName에 의해 명시된 프라퍼티에 값을 가져가고 Array객체로 결과를 반환한다.
reject(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 집합내 각각의 요소를 위한 iterator함수를 호출하고 false로 해석하는 값을 반환하는 iterator함수를 야기하는 모든 요소를 가진 Array를 반환한다. 이 함수는 findAll()과는 반대되는 함수이다..
select(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 findAll()과 같다.
sortBy(iterator) instance iterator: Function(value, index)를 충족하는 함수 객체 iterator함수 호출결과를 따르는 정렬된 모든 요소를 가진 Array을 반환.
toArray() instance (none) 집합의 모든 요소를 가지는 Array를 반환.
zip(collection1[, collection2 [, ... collectionN [,transform]]]) instance collection1 .. collectionN: 병합될 목록, transform: Function(value, index)를 충족하는 함수 객체 현재의 집합으로 각각의 주어진 집합을 병합한다. 이 병합 작업은 같은 수의 요소를 가진 새로운 배열을 반환한다. 현재 집합과 각각의 요소가 각각의 병합된 집합으로부터 같은 인덱스를 가진 요소의 배열(이것을 하위 배열이라고 부르자.)이다. transform함수가 주어진다면, 각각의 하위 배열은 반환되기 전에 이 함수에 의해 변형딜것이다. 빠른 예제 : [1,2,3].zip([4,5,6], [7,8,9]).inspect() 는 "[[1,4,7],[2,5,8],[3,6,9] ]" 를 반환한다.

Hash 객체

Hash 객체는 hash구조를 구현한다. 이를테면, Key:Value쌍의 집합.

Hash객체내 각각의 항목은 두개의 요소(첫번째는 key, 두번째는 value)를 가진 배열이다. 각각의 항목은 두개의 프라퍼티(keyvalue)를 가진다.

메소드 종류 인자 상세설명
keys() instance (none) 모든 항목의 key를 가진 Array을 반환
values() instance (none) 모든 항목의 value를 가진 Array을 반환
merge(otherHash) instance otherHash: Hash 객체 hash와 전달된 다른 hash를 조합하고 새로운 결과 hash를 반환
toQueryString() instance (none) 쿼리 문자열처럼 포맷팅된 문자열로 hash의 모든 항목을 반환. 이를테면 'key1=value1&key2=value2&key3=value3'
inspect() instance (none) key:value쌍을 가진 hash의 포맷팅된 문자열 표현을 반환하기 위해 변경(오버라이드)

ObjectRange 클래스

Enumerable으로부터 상속

상위 경계나 하위 경계로 값들의 범위를 표시

 

프라퍼티 타입 종류 상세설명
start (any) instance 범위의 시작값
end (any) instance 범위의 마지막값
exclusive Boolean instance 경계자체가 범위의 일부인지 판단

 

메소드 종류 인자 상세설명
[ctor](start, end, exclusive) constructor start: 시작값, end: 마지막값, exclusive: 경계가 범위내 포함되는가.? 하나의 range객체를 생성한다. start 에서 end로 범위를 지정한다. startend가 같은 타입의 객체이고 succ()메소드를 가져야만 한다.
include(searchedValue) instance searchedValue: 검색할 값 주어진 값이 범위내 값인지 체크. truefalse값을 반환한다.

The Class object

Class 객체는 라이브러리에서 다른 클래스를 선언할때 사용된다. 클래스를 선언할때 이 객체를 사용하는 것은 생성자로 제공되는 initialize()메소드를 지원하기 위한 새로운 클래스를 발생시킨다.

아래의 샘플을 보라.

//declaring the class
var MySampleClass = Class.create();
//defining the rest of the class implmentation
MySampleClass.prototype = {
    initialize: function(message) { this.message = message; },
    showMessage: function(ajaxResponse) { alert(this.message); }
};
//now, let's instantiate and use one object
var myTalker = new MySampleClass('hi there.');
myTalker.showMessage();
//displays alert

메소드 종류 인자 상세설명
create(*) instance (any) 새로운 클래스를 위한 생성자를 정의

Ajax 객체

이 객체는 AJAX기능을 제공하는 많은 다른 클래스를 위한 root와 명명공간(namespace)처럼 제공한다.

프라퍼티 타입 종류 상세설명
activeRequestCount Number instance 진행중인 AJAX요청의 수.

메소드 종류 인자 상세설명
getTransport() instance (none) 새로운 XMLHttpRequest 객체를 반환

Ajax.Responders 객체

Enumerable로 부터 상속되었다

이 객체는 Ajax관련 이벤트가 발생할때 호출될 객체의 목록을 보존한다. 예를 들어, 당신이 AJAX작업을 위한 전역 예외 핸들러를 연결하길 원한다면 이 객체를 사용할수 있다.

 

프라퍼티 타입 종류 상세설명
responders Array instance 객체의 목록은 AJAX이벤트 알림(notifications)을 위해 등록되었다..

 

메소드 종류 인자 상세설명
register(responderToAdd) instance responderToAdd: 호출될 메소드를 가진 객체 responderToAdd인자를 전달하는 객체는 AJAX이벤트(이를테면, onCreate, onComplete, onException 등등)처럼 명명된 메소드를 포함해야만 한다. 유사한 이벤트가 발생하면, 적절한 이름을 가진 메소드를 포함하는 모든 등록된 객체가 호출되는 메소드를 가질것이다.
unregister(responderToRemove) instance responderToRemove: list로부터 제거될 객체 responderToRemove 인자로 전달되는 객체는 등록된 객체의 list로부터 제거될것이다.
dispatch(callback, request, transport, json) instance callback: 보고되는 AJAX이벤트 이름, request: 이벤트를 책임지는 the Ajax.Request 객체, transport: AJAX호출을 가지는 XMLHttpRequest 객체, json: 응답의 X-JSON 헤더(존재할때만) 등록된 객체의 목록을 통해 실행하는 것은 callback 인자내 결정된 메소드를 가지는 것을 찾는다. 호출되는 각각의 메소드는 다른 3개의 인자를 전달한다. AJAX응답이 몇몇 JSON컨텐츠를 가지는 X-JSON HTTP 헤더를 포함한다면, 이것은 평가되고 json인자로 전달될것이다. 만약 이벤트가 onException라면, transport인자는 대신에 예외를 가질것이고 json은 전달되지 않을것이다.

Ajax.Base 클래스

이 클래스는 Ajax객체내 정의된 다른 대부분의 클래스를 위한 기본(base)클래스처럼 사용된다.

메소드 종류 인자 상세설명
setOptions(options) instance options: AJAX 옵션 AJAX작업을 위해 필요한 옵션 셋팅
responseIsSuccess() instance (none) 만약 AJAX작업이 성공한다면 true를 반환하고, 실패한다면 false를 반환
responseIsFailure() instance (none) responseIsSuccess()와는 반대.

Ajax.Request 클래스

Ajax.Base로 부터 상속

AJAX 작업을 캡슐화

프라퍼티 타입 종류 상세설명
Events Array static AJAX작업중 보고되는 가능한 이벤트/상태의 목록. 목록은 'Uninitialized', 'Loading', 'Loaded', 'Interactive', 그리고 'Complete.'를 포함한다.
transport XMLHttpRequest instance AJAX작업을 가지는 XMLHttpRequest 객체
url String instance 요청에 의해 대상이 되는 URL

 

메소드 종류 인자 상세설명
[ctor](url, options) constructor url: 꺼내기 위한 url, options: AJAX 옵션 주어진 옵션을 사용하여 주어진 url을 호출할 이 객체의 하나의 인스턴스를 생성. 중요사항: 선택된 url은 브라우저의 보안 셋팅을 위한 대상이 될 가치가 없다. 많은 경우 브라우저는 현재 페이지처럼 같은 호스트로부터가 아니라면 url을 가져오지 않을것이다. 당신은 설정을 피하거나 사용자의 브라우저를 제한하기 위한 로컬 url만을 사용할 것이다.
evalJSON() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 AJAX응답내 존재하는 X-JSON HTTP헤더의 컨텐츠를 평가하기 위해 내부적으로 호출된다.
evalReponse() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. AJAX응답이 text/javascriptContent-type헤더를 가진다면, 응답 몸체는 평가되고 이 메소드는 사용될것이다.
header(name) instance name: HTTP 헤더명 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 AJAX응답의 HTTP헤더의 컨텐츠를 가져오기 위해 내부적으로 호출된다.
onStateChange() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 AJAX호출 상태 변경시 객체 자체에 의해 호출된다.
request(url) instance url: AJAX호출을 위한 url 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 생성자를 호출하는 동안 벌써 호출되었다.
respondToReadyState(readyState) instance readyState: 상태 숫자값(1 에서 4) 이 메소드는 대개 외부에서 호출되지 않는다. 이것은 AJAX호출 상태가 변경될때 객체 자체에 의해 호출된다.
setRequestHeaders() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 HTTP요청을 하는 동안 보내어질 HTTP헤더를 조합하기 위한 객체 스스로에 의해 호출된다.

options 인자 객체

AJAX작업의 중요한 부분은 options 인자이다. 이것은 기대되는 프라퍼티를 가지는 동안 어떠한 객체도 전달될수 있다. 이것은 AJAX호출을 위해 익명 객체를 생성하는 것이 공통적이다.

프라퍼티 타입 디폴트 상세설명
method String 'post' HTTP요청의 메소드
parameters String '' 요청에 전달한 값들의 url형태의 목록
asynchronous Boolean true AJAX호출이 비동기적으로 만들어지는지 표시
postBody String undefined HTTP POST의 경우 요청의 몸체내 전달되는 내용
requestHeaders Array undefined 요청과 함께 전달되기 위한 HTTP헤더의 목록. 이 목록은 많은 수의 항목을 가져야 한다. 나머지 항목은 사용자 정의 헤더의 이름이다. 그리고 다음의 항목은 헤더의 문자열 값이다. 예제 : ['my-header1', 'this is the value', 'my-other-header', 'another value']
onXXXXXXXX Function(XMLHttpRequest) undefined 각각의 이벤트/상태가 AJAX호출이 발생하는 동안 도착할때 호출될 사용자정의 함수. 예제 var myOpts = {onComplete: showResponse, onLoaded: registerLoaded};. 사용되는 함수는 AJAX작업을 가지는 XMLHttpRequest객체를 포함하는 하나의 인자를 받을것이다.
onSuccess Function(XMLHttpRequest) undefined AJAX호출이 성공적으로 완성될때 호출될 사용자정의 함수. 사용되는 함수는 AJAX작업을 가지는 XMLHttpRequest객체를 포함하는 하나의 인자를 받을것이다.
onFailure Function(XMLHttpRequest) undefined AJAX호출이 에러를 가진채 끝날때 호출될 사용자정의 함수. 사용되는 함수는 AJAX작업을 가지는 XMLHttpRequest객체를 포함하는 하나의 인자를 받을것이다.
insertion Function(Object, String) null 삽입하기 위해 호출되는 함수는 텍스트를 요소로 반환한다. 함수는 수정되기 위한 요소객체와 Ajax.Updater객체에만 적용되는 응답 텍스트의 두개의 인자를 가지고 호출된다.
evalScripts Boolean undefined, false 스크립트 블럭이 응답이 도착했을때 평가할지를 판단. Ajax.Updater객체에만 적용.
decay Number undefined, 1 Ajax.PeriodicalUpdater 객체는 받은 응답이 마지막 것과 같을때 비율을 새롭게 하여 연속적인 후퇴를 결정. 예를 들어, 당신이 2를 사용한다면, 새롭게 된것중에 하나가 이전것과 같은 결과를 만든후에, 객체는 다음 refresh를 위한 시간의 두배를 기다릴것이다. 이것은 다시 반복한다면, 객체는 4배를 기다릴것이다. 이것을 후퇴를 피하기 위해 정의되지 않거나 1을 사용하도록 남겨두라.

Ajax.Updater 클래스

Ajax.Request로 부터 상속

요청된 url이 당신 페이지의 특정 요소내 직접적으로 삽입하길 원하는 HTML을 반환할때 사용된다. 당신은 url이 도착을 평가할 <script>블럭을 반환할때 이 객체를 사용할수 있다. 스크립트로 작업하기 위해 evalScripts 옵션을 사용하라.

프라퍼티 타입 종류 상세설명
containers Object instance 이 객체는 두개의 프라퍼티(containers.success 는 AJAX호출이 성공할때 사용될것이다. 그리고 AJAX호출이 실패한다면 containers.failure가 사용될것이다.)를 포함한다.

메소드 종류 인자 상세설명
[ctor](container, url, options) constructor container: 이것은 요소의 id, 요소객체 자체, 또는 두개의 프라퍼티(AJAX호출이 성공했을때 사용될 object.success 요소(또는 id), 그리고 AJAX호출이 실패했을때 사용될 object.failure요소(또는 id))를 가지는 객체가 될수 있다. url: 가져오기 위한 url, options: AJAX 옵션 주어진 옵션을 사용하여 주어진 url을 호출할 이 객체의 하나의 인스턴스를 생성.
updateContent() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 응답을 받았을때 객체 자체에 의해 호출된다. 이것은 HTML로 적절한 요소를 수정하거나 insertion옵션내 전달되는 함수를 호출할것이다. 이 함수는 두개의 인자(수정되기 위한 요소와 응답 텍스트)를 가지고 호출될것이다.

Ajax.PeriodicalUpdater 클래스

Ajax.Base로 부터 상속

이 클래스는 반복적으로 인스턴스화하고 페이지에서 요소를 새롭게 하거나 Ajax.Updater가 수행할수 있는 다른 작업중 어느것을 수행하기 위한 Ajax.Updater객체를 사용한다. 좀더 많은 정보를 위해 Ajax.Updater 참조를 체크하라.

프라퍼티 타입 종류 상세설명
container Object instance 이 값은 Ajax.Updater생성자에 일관적으로 전달될것이다.
url String instance 이 값은 Ajax.Updater의 생성자에 일관적으로 전달될것이다.
frequency Number instance 초단위의 refresh간격. 디폴트는 2초. 이 숫자는 Ajax.Updater 객체를 호출할때 현재 축소(decay)에 의해 곱해질것이다.
decay Number instance 작업을 재-수행할때 적용될 축소(decay)레벨을 유지
updater Ajax.Updater instance 가장 최신에 사용된 Ajax.Updater 객체
timer Object instance 다른 refresh를 위한 시각일때 객체를 알리기 위해 사용되는 자바스크립트 타이머

메소드 종류 인자 상세설명
[ctor](container, url, options) constructor or container:이것은 요소의 id, 요소객체 자체, 또는 두개의 프라퍼티(AJAX호출이 성공할때 사용될 object.success 요소(나 id), AJAX호출이 실패할때 사용할 object.failure 요소(나 id))를 가지는 객체가 될수 있다. url: 가져오기 위한 url, options: AJAX 옵션 주어진 옵션을 사용하여 주어진 url을 호출할 이 객체의 하나의 인스턴스를 생성
start() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것의 정기적인 작업 수행을 시작하기 위해 객체 자체에 의해 호출된다.
stop() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것의 정기적인 작업 수행을 시작하기 위해 객체 자체에 의해 호출된다.
updateComplete() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 요청을 완성한 후에 사용되는 Ajax.Updater에 의해 호출된다. 이것은 다음 refresh스케줄링 하기 위해 사용된다.
onTimerEvent() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 다음 수정을 위한 시각일때 내부적으로 호출된다.

Element 객체

이 객체는 DOM내 요소를 변경하기 위해 몇몇 유틸리티성 함수들을 제공한다.

메소드 종류 인자 상세설명
visible(element) instance element: element 객체 또는 아이디 요소가 눈에 보이는지 표시하는 Boolean값을 반환
toggle(elem1 [, elem2 [, elem3 [...]]]) instance elemN: element 객체 또는 아이디 각각의 전달된 요소의 가시성(visibility)을 토글(toggle)한다.
hide(elem1 [, elem2 [, elem3 [...]]]) instance elemN: element 객체 또는 아이디 style.display'none'로 셋팅하여 각각의 요소를 숨긴다.
show(elem1 [, elem2 [, elem3 [...]]]) instance elemN: element 객체 또는 아이디 style.display''로 다시 셋팅하여 각각의 요소를 보여준다.
update(element, html) instance element: element 객체 또는 아이디, html: html 컨텐츠 주어진 html인자를 가지는 요소의 내부 html을 대체. 주어진 html이 <script>블럭을 포함한다면, 그것들은 포함되지는 않지만 평가될것이다.
remove(element) instance element: element 객체 또는 아이디 문서로 부터 요소를 제거한다.
getHeight(element) instance element: element 객체 또는 아이디 요소의 offsetHeight값을 반환
addClassName(element, className) instance element: element 객체 또는 아이디, className: CSS 클래스명 주어진 class명을 요소의 class명으로 추가
hasClassName(element, className) instance element: element 객체 또는 아이디, className: name of a CSS class 요소가 class명중에 하나로 주어진 class명을 가진다면 true를 반환
removeClassName(element, className) instance element: element 객체 또는 아이디, className: CSS 클래스명 요소의 class명으로 부터 주어진 class명을 제거
cleanWhitespace(element) instance element: element 객체 또는 아이디 요소의 자식노드에서 공백을 제거

The Abstract 객체

이 객체는 라이브러리내 다른 클래스를 위한 root처럼 제공한다. 이것은 어떤 프라퍼티나 메소드도 가지지 않는다. 이 객체에 정의된 클래스는 전통적인 추상 클래스처럼 처리된다.

Abstract.Insertion 클래스

이 클래스는 동적으로 내용물을 추가할 다른 클래스를 위한 기본 클래스처럼 사용된다. 이 클래스는 추상 클래스처럼 사용된다.

메소드 종류 인자 상세설명
[ctor](element, content) constructor element: element 객체 또는 아이디, content: 삽입되는 HTML 동적 내용물 삽입을 도울 객체를 생성

프라퍼티 타입 종류 상세설명
adjacency String static, parameter 내용물이 주어진 요소에 대해 상대적으로 위치할 지점을 명시하는 파라미터. 가능한 값은 'beforeBegin', 'afterBegin', 'beforeEnd', 그리고 'afterEnd'.
element Object instance 삽입이 상대적으로 만들어질 요소객체
content String instance 삽입될 HTML.

Insertion 객체

이 객체는 라이브러리내 다른 클래스를 위한 root처럼 제공한다. 이것은 어떠한 프라퍼티나 메소드를 가지지 않는다. 이 객체에 정의된 클래스는 전통적인 추상 클래스처럼 처리된다.

Insertion.Before 클래스

Abstract.Insertion로 부터 상속

요소 앞에 HTML삽입

메소드 종류 인자 상세설명
[ctor](element, content) constructor element: element 객체 또는 아이디, content: 삽입되는 HTML Abstract.Insertion으로 부터 상속. 동적으로 내용물을 삽입하는 것을 돕는 객체를 생성

다음의 코드는

<br>Hello,
<span id="person" style="color:red;">Wiggum. How's it going?</span>
<script> new Insertion.Before('person', 'Chief '); </script>

다음처럼 HTML이 변경될것이다.

<br>Hello, Chief
<span id="person" style="color:red;">Wiggum. How's it going?</span>

Insertion.Top 클래스

Abstract.Insertion로 부터 상속

요소아래의 첫번째 자식으로 HTML을 삽입. 이 내용물은 요소의 열기 태그뒤에 위치할것이다.

메소드 종류 인자 상세설명
[ctor](element, content) constructor element: element 객체 또는 아이디, content: 삽입되는 HTML Abstract.Insertion으로부터 상속. 동적으로 내용물을 삽입하는 것을 돕는 객체 생성

다음의 코드는


<br>Hello,
<span id="person" style="color:red;">Wiggum. How's it going?</span>
<script> new Insertion.Top('person', 'Mr. '); </script>

다음처럼 HTML이 변경될것이다.

<br>Hello,
<span id="person" style="color:red;">Mr. Wiggum. How's it going?</span>
 

Insertion.Bottom 클래스

Abstract.Insertion로 부터 상속

요소아래의 마지막 자식으로 HTML삽입. 내용물은 요소의 닫기 태그앞에 위치할것이다.

메소드 종류 인자 상세설명
[ctor](element, content) constructor element: element 객체 또는 아이디, content: HTML to be inserted Abstract.Insertion로 부터 상속. 동적으로 내용물을 삽입하는 것을 돕는 객체 생성

다음의 코드는


<br>Hello,
<span id="person" style="color:red;">Wiggum. How's it going?</span>
<script> new Insertion.Bottom('person', " What's up?"); </script>

다음처럼 HTML이 변경될것이다.

<br>Hello,
<span id="person" style="color:red;">Wiggum. How's it going? What's up?</span>

Insertion.After 클래스

Abstract.Insertion로 부터 상속

요소의 닫기 태그뒤 HTML삽입

메소드 종류 인자 상세설명
[ctor](element, content) constructor element: element 객체 또는 아이디, content: HTML to be inserted Abstract.Insertion으로부터 상속. 동적으로 내용물을 삽입하는 것을 돕는 객체 생성

다음의 코드는


<br>Hello,
<span id="person" style="color:red;">Wiggum. How's it going?</span>
<script> new Insertion.After('person', ' Are you there?'); </script>

다음처럼 HTML이 변경될것이다.


<br>Hello, <span id="person" style="color:red;">Wiggum. How's it going?</span> Are you there?

Field 객체

이 객체는 폼내 input필드와 작동하기 위한 몇가지 유틸리티성 함수를 제공한다.

메소드 종류 인자 상세설명
clear(field1 [, field2 [, field3 [...]]]) instance fieldN: field element 객체 또는 아이디 field요소로부터 각각 전달된 값을 지움(clear)
present(field1 [, field2 [, field3 [...]]]) instance fieldN: field element 객체 또는 아이디 모든 폼 field가 빈값이 아니라면 true를 반환
focus(field) instance field: field element 객체 또는 아이디 주어진 폼 field로 입력 포커스 이동
select(field) instance field: field element 객체 또는 아이디 텍스트 선택을 지원하는 field내 값을 선택
activate(field) instance field: field element 객체 또는 아이디 포커스를 이동하고 텍스트 선택을 지원하는 field내 값을 선택

Form 객체

이 객체는 데이터 항목 폼과 그것들의 입력 field와 작동하기 위한 몇몇 유틸리티성 함수를 제공한다.

메소드 종류 인자 상세설명
serialize(form) instance form: form element 객체 또는 아이디 'field1=value1&field2=value2&field3=value3'처럼 field명과 값의 url형태의 목록을 반환
getElements(form) instance form: form element 객체 또는 아이디 폼내 모든 입력 field를 포함하는 Array 반환
getInputs(form [, typeName [, name]]) instance form: form element 객체 또는 아이디, typeName: input요소의 타입, name: input요소명. 폼내 모든 <input>요소를 포함하는 Array 반환. 선택적으로 목록은 요소의 타입이나 name속성에 의해 필터링 될수 있다.
disable(form) instance form: form element 객체 또는 아이디 폼내 모든 입력 field를 사용불가상태로 만들기
enable(form) instance form: form element 객체 또는 아이디 폼내 모든 입력 field를 사용가능하게 만들기
focusFirstElement(form) instance form: form element 객체 또는 아이디 첫번째 가시성을 활성화하고, 폼내 입력 field를 가능하게 하기
reset(form) instance form: form element 객체 또는 아이디 폼을 리셋하기. form객체의 reset()메소드와 같다.

Form.Element 객체

이 객체는 폼요소와 작동하기 위한 몇몇 유틸리티성 함수를 제공한다.

메소드 종류 인자 상세설명
serialize(element) instance element: element 객체 또는 아이디 'elementName=elementValue'처럼 요소의 name=value 짝을 반환
getValue(element) instance element: element 객체 또는 아이디 요소의 값을 반환

Form.Element.Serializers 객체

이 객체는 폼요소의 현재 값을 가져오기 위해 라이브러리 내부적으로 사용되는 몇몇 유틸리티성 함수를 제공한다.

메소드 종류 인자 상세설명
inputSelector(element) instance element: radio 버튼이나 checkbox처럼 checked프라퍼티를 가지는 form요소의 객체 또는 아이디 ['elementName', 'elementValue']처럼 요소의 이름과 값을 가지는 Array을 반환
textarea(element) instance element: textbox, button 또는 password필드처럼 value프라퍼티를 가지는 form요소의 객체 또는 아이디. ['elementName', 'elementValue']처럼 요소의 이름과 값을 가지는 Array를 반환
select(element) instance element: <select> 요소의 객체 또는 아이디 ['elementName', 'selOpt1 selOpt4 selOpt9']처럼 요소의 이름과 모든 선택된 옵션의 값이나 텍스트를 가지는 Array를 반환

Abstract.TimedObserver 클래스

이 클래스는 값이 변경(또는 프라퍼티가 클래스정의를 얻어내는)될때까지 하나의 요소를 모니터링할 다른 클래스를 위한 기본클래스처럼 사용된다. 이 클래스는 추상클래스처럼 사용된다.

하위클래스는 요소의 입력값, style프라퍼티중 하나, 또는 테이블내 row의 수, 또는 당신이 추적하고자 하는 모든것을 모니터링하기 위해 생성될수 있다.

얻어낸 클래스는 요소내 모니터링되는 현재 값을 무엇인지 판단하기 위한 메소드를 구현하는 것이다.

instance, abstract
메소드 종류 인자 상세설명
[ctor](element, frequency, callback) constructor element: element 객체 또는 아이디, frequency: 초단위 간격, callback: 요소가 변경될때 호출되는 함수 요소를 모니터링할 객체 생성
(none)
registerCallback() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 요소 모니터링릉 시작하기 위한 객체 자체에 의해 호출된다.
onTimerEvent() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 요소를 체크하기 위해 정기적으로 객체 자체에 의해 호출된다.

프라퍼티 타입 상세설명
element Object 모니터링되는 요소객체
frequency Number 이것은 체크사이에 초단위 간격으로 이루어진다.
callback Function(Object, String) 요소가 변경될때마다 호출되기 위한 함수. 이것은 요소객체와 새로운 값을 받을것이다.
lastValue String 요소내 확인되는 마지막 값

Form.Element.Observer 클래스

Abstract.TimedObserver로 부터 상속

폼 입력 요소의 값을 모니터링하는 Abstract.TimedObserver의 구현물. 값 변경을 보고하는 이벤트를 드러내지 않는 요소를 모니터링하고자 할때 이 클래스를 사용하라. 이 경우 당신은 Form.Element.EventObserver 클래스를 대신 사용할수 있다.

메소드 종류 인자 상세설명
[ctor](element, frequency, callback) constructor element: element 객체 또는 아이디, frequency: interval in seconds, callback: function to be called when the element changes Abstract.TimedObserver으로부터 상속. 요소의 value프라퍼티를 모니터링할 객체를 생성.
getValue() instance (none) 요소의 값을 반환

Form.Observer 클래스

Abstract.TimedObserver로 부터 상속

폼내 데이터 항목 요소의 값이 변경하는지를 모니터링하는 Abstract.TimedObserver의 구현물. 당신이 값 변경을 보고하는 이벤트를 드러내지 않는 요소를 포함하는 폼을 모니터링하고자 할때 이 클래스를 사용하라. 이 경우 당신은 Form.EventObserver 클래스를 대신 사용할수 있다.

메소드 종류 인자 상세설명
[ctor](form, frequency, callback) constructor form: form 객체 또는 아이디, frequency: 초단위 간격, callback: form내 데이터 항목 요소가 변경될때 호출되는 함수 Abstract.TimedObserver로부터 상속. 변경하기 위한 폼을 모니터링할 객체 생성.
getValue() instance (none) 모든 폼의 데이터의 직렬화를 반환

Abstract.EventObserver 클래스

이 클래스는 요소를 위해 값-변경 이벤트가 발생할때마다 콜백함수를 수행하는 다른 클래스를 위한 기본 클래스처럼 사용된다.

Abstract.EventObserver 타입의 다중 객체는 다른것을 지우지 않고 같은 요소로 묶일수 있다. 콜백은 요소에 할당되는 순서대로 수행될것이다.

트리거 형태의 이벤트는 radio버튼과 checkbox를 위해서는 onclick이고 대개의 textbox와 리스트박스/드랍다운을 위해서는 onchange이다.

얻어낸 클래스는 요소내 모니터링되는 현재 값을 무엇인지 판단하기 위한 메소드를 구현하는 것이다.

instance, abstract
메소드 종류 인자 상세설명
[ctor](element, callback) constructor element: element 객체 또는 아이디, callback: 이벤트가 발생할때 호출되는 함수 요소를 모니터링할 객체 생성.
(none)
registerCallback() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 요소의 이벤트를 자체적으로 묶는 객체에 의해 호출된다.
registerFormCallbacks() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 폼내 각각의 데이터 항목 요소의 이벤트로 자체적으로 묶기 위한 객체에 의해 호출된다.
onElementEvent() instance (none) 이 메소드는 대개 외부적으로 호출되지 않는다. 이것은 요소의 이벤트로 묶일것이다.

프라퍼티 타입 상세설명
element Object 모니터링되는 요소객체
callback Function(Object, String) 요소가 변경될때마다 호출되기 위한 함수. 이것은 요소객체와 새로운 값을 받을것이다.
lastValue String 요소내 확인되는 마지막 값

Form.Element.EventObserver 클래스

Abstract.EventObserver로 부터 상속

요소내 값 변경을 감지하기 위한 폼 데이터 항목 요소의 적절한 이벤트를 위한 콜백 함수를 수행하는 Abstract.EventObserver의 구현물. 만약 요소가 변경을 보고하는 이벤트를 드러내지 않는다면, 당신은 Form.Element.Observer 클래스를 대신 사용할수 있다.

메소드 종류 인자 상세설명
[ctor](element, callback) constructor element: element 객체 또는 아이디, callback: function to be called when the event happens Abstract.EventObserver로 부터 상속. 요소의 value프라퍼티를 모니터링할 객체 생성.
getValue() instance (none) 요소의 값 반환.

Form.EventObserver 클래스

Abstract.EventObserver로 부터 상속

값이 변결될때 감지하기 위한 요소의 이벤트를 사용하여 폼내 포함되는 어느 데이터 항목 요소에 변경을 모니터링하는 Abstract.EventObserver의 구현물. 만약 폼이 변경을 보고하는 이벤트를 드러내지 않는 요소를 포함한다면, 당신은 Form.Observer 클래스를 대신 사용할수 있다.

메소드 종류 인자 상세설명
[ctor](form, callback) constructor form: form 객체 또는 아이디, callback: form내 데이터 항목 요소가 변경될때 호출되는 함수 Abstract.EventObserver로부터 상속. 변경을 위해 폼을 모니터링할 객체 생성.
getValue() instance (none) 모든 폼의 데이터 직렬화를 반환

Position 객체 (예비 문서)

이 객체는 요소 위치할당을 작업할때 돕는 수많은 함수를 제공한다.

메소드 종류 인자 상세설명
prepare() instance (none)

스크롤 위치내 변경을 수용하기 위한 deltaXdeltaY 프라퍼티 조정. 페이지 스크롤후 withinIncludingScrolloffset를 호출하기 전에 이 메소드를 호출하는 것을 기억하라.

realOffset(element) instance element:object

요소에 영향을 끼치는 어느 스크롤 offset를 포함하는 요소의 정확한 스크롤 offset를 가진 Array을 반환. 이 결과 배열은 [total_scroll_left, total_scroll_top]과 유사.

cumulativeOffset(element) instance element:object

위치가 할당된 부모 요소에 의해 부과된 어느 offset를 포함하는 요소의 정확한 위치가 할당된 offset를 가진 Array을 반환. 결과 배열은[total_offset_left,total_offset_top] 과 유사

within(element, x, y) instance

element:object, x 와 y: 위치 조정

만약 주어진 지점이 주어진 요소의 직사각형내 조정이 되는지 테스트.

withinIncludingScrolloffsets(element, x, y)

instance

element:object, x and y:
coordinates of a point

 
overlap(mode, element) instance

mode:
'vertical' 나 'horizontal', element: object

within()은 이 메소드가 호출되기 전에 호출될 필요가 있다. 이 메소드는 요소에서 겹치는 것을 조정하는 세분화정도를 표현하는 0.0과 1.0사이의 10진수를 반환할것이다. 예를 들면, 만약 요소가 100px를 가지는 정사각형 DIV이고 (300,300)에 위치한다면,
within(divSquare, 330, 330);
overlap('vertical', divSquare);
은 DIV의 top border로부터 10%(30px)를 가리키는 것을 의미하는 0.10을 반환할것이다.

clone(source, target) instance

source:
element 객체 또는 아이디,
target: element 객체 또는 아이디

source요소에 대해 똑같이 target요소의 크기를 다시 조정하고 다시 위치를 지정

 
 

Prototype.js 가이드 02 _ Ajax support

WEB2.0/ajax | 2006. 5. 10. 20:31
Posted by 시반

The Ajax 객체

앞서의 함수들은 분명 좋은 코드들이지만 그러한 함수들을 구현할 능력이 있거나 이미 유사한 자신만의 함수를 사용하고 있을지 모른다. 하지만 prototype.js를 사용하는 이유는 대부분 Ajax기능을 쉽게 사용하길 원하기 때문이기에 이제 prototype.js를 사용하여 AJAX로직을 좀더 쉽게 작성할 수있는 방법을 살펴보기로 하자.

 

먼저 ProtoType라이브러니는 Ajax 기능 구현을 위해 Ajax 객체라는 것을 제공하고 있다

AJAX객체는 AJAX관련 함수를 작성시 만들어지는 코드의 단순화와 캡슐화를 위해 ProtoType라이브러리에 미리 정의된 객체이며 AJAX객체는 AJAX로직이 캡슐화되어 제공되어지는 다수의 클래스를 포함하고 있다. .

Ajax.Request 클래스 사용하기

만약 어떠한 헬퍼(helper) 라이브러리도 사용하지 않는다면 Ajax기능을 사용하기 위해 수많은 코드에서  XMLHttpRequest 객체를 생성해야 것이며 각 실행 단계마다 비동기적으로 체크를 해야 할것이며. 그리고나서 응답을 뽑아내는 것을 반복할 것이다.

protoType라이브러리에서는 이러한 기능을 지원하기 위해 Ajax.Request클래스를 정의하고 있다.

 

라이브러리를 통해 Ajax 어플리케이션을 만들기 위해서는 다음과 같은 방식으로 Ajax.Request 객체를 생성하여야 한다

 var myAjax = new Ajax.Request(

              url,

              {method: 'post', parameters: data, onComplete: ajax_response}

              );

 

위에서 사용된 Ajax.Request객체의 생성자의 두번째 파라미터의 의미는 Ajax호출을 위한 옵션을 정의하고 있다 즉 위의 예에서는 HTTP POST명령을 통해 첫번째 파라미터인 url을 호출할 것이며 변수 data에 포함된 조회문자열을 전달하고 응답을 받아들이는 작업을 마칠 때 ajax_response()함수를 호출하라는 프로퍼티를 가지는 Ajax.Request객체를 생성하라는 뜻이다

 

예를 들었던 프로퍼티 외에 AJAX를 비동기적으로 서버에 호출할지를 결정( true 또는 false) 할 수 있는 asynchronous 프로퍼티(디폴트 값은 true이다.) 등 Ajax.Request 객체 내에서 정의하고 활성화 시킬수 있는 몇개의 프로퍼티가 더 존재하고 있다

 

XMLHttpRequest는 HTTP호출을 하는 동안 진행과정(Loading, Loaded, Interactive,Complete)를 알릴수 있는데 각 단계마다 사용자정의함수를 통해 Ajax.Request객체를 호출할 수 있으며 일반적으로 Complete 상태에서 Ajax.Request객체를 호출하고 있다

그 방법은 위의 예제(onComplete)처럼 요청옵션내 onXXXXX에서 간단히 설정하기만 하면  그 설정된 이름을 가진 함수를 통하여 XMLHttpRequest객체 자체가 될 하나의 인자와 response HTTP header(X-JSON)라는 또 하나의 인자를 가지는 객체를 전달 받을 수 있을 것이다

당신은 반환 데이타를 얻기 위해 이 객체를 사용하거나 호출된 HTTP 결과 코드를 포함하는 Status프로퍼티 체크를 하기 위해 이 객체를 사용할 지도 모른다.

 

또 다른 두개의 옵션은 결과에 대한 처리수행을 위해 사용될수 있다.

onSuccess옵션을 통해 AJAX호출이 에러없이 수행될 때 호출할 함수를 명시할 수 있다.

onFailure옵션은 반대로 에러가 발생할때 호출될 함수를 명시할 수 있다.

이 두가지 옵션에서도 onXXXXX에서 선택한 함수와 마찬가지로  AJAX호출시 전달되는 XMLHttpRequest객체나  evaluated X-JSON header를 전달하도록 할수 있을 것이다.

 

앞서 이야기 한 내용들을 토대로 간단한 예제를 만들어 보기로 하자

먼저 Ajax.Request 객체를 생성하는 함수를 만든다

 

function ajax_request(url, data) {

     var myAjax = new Ajax.Request(

              url,

              {method: 'post', parameters: data, onComplete: ajax_response}

              );

    }

 

두번째로 request가 끝나게 되면 호출될 ajax_response()라는 함수로 만들어 보자

 

function ajax_response(originalRequest) {

      if(!bHasRedirect) {

         //process originalRequest.responseText;

      } else {

          bHasRedirect = false;

          ajax_request(originalRequest.responseText, "");

      }

   }

 

이제 Ajax Request를 만들고 나면 만약 전역변수로 bHashRedirec를가 true로 설정하게 하는 또다른 Ajax.Request가 만들어지기거나 함수내 originalRequest.responseText()를 통하여 수행할 더이상의 코드가 존재하지 않을 때까지   response는 항상 ajax_response()를 호출할 것이다

 

Ajax.Responders 객체 사용하기

1.4.0 버전에서, 이벤트 반환 핸들링에 대하여 새로이 소개되고 있는 것이 있는데 만약 AJAX호출이 발생하더라도 특정 이벤트를 위해 항상 수행되어야 하는 코드를 가지고 있다면 이 새로운 Ajax.Responders 객체를 사용할수 있다고 한다 .

 

<script> 
     var myGlobalHandlers = {
         onCreate: function(){
             Element.show('systemWorking'); 
         }, 
         onComplete: function(){
             if(Ajax.activeRequestCount == 0){
                 Element.hide('systemWorking');
             }
         }
     };
 
     Ajax.Responders.register(myGlobalHandlers);
</script>

<div id='systemWorking'><img src='spinner.gif'>Loading...</div>

 

위의 예에서와 같이 AJAX호출이 진행중이라는 시각적 표시를 보여주길 원한다고 했을 때. 당신은 두개의 전역 이벤트 핸들러를 사용할수 있다. 하나는 첫번째 호출이 시작되었을때 아이콘을 보여주는것이고 다른 하나는 적어도 하나가 끝났을때 아이콘을 숨기는 것이다.

 

더 자세한 사항은 Ajax.Request 참조문서나 options 참조문서를 참조하길 바란다

 

Ajax.Updater 클래스 사용하기

Ajax.Updater 클래스는 어떤 요소에서 Ajax 호출로부터 반환된 HTML을 채우게 되는지 알려주는 클래스입니다.말보다 한줄의 소스가 더 쉽게 이해가 될 것 같습니다

<script>

     function getHTML()

       {

           var url = 'http://yourserver/app/getSomeHTML';

           var pars = 'someParameter=ABC';

           var myAjax = new Ajax.Updater(

                               'placeholder',

                               url,

                               {method: 'get',parameters: pars });

       }

</script>

 

<input type=button value=GetHtml onclick="getHTML()">

 

<div id="placeholder"></div>

 

Ajax.Updater 객체생성 코드는 Ajax.Request객체와 유사하지만.

인자가 하나 더 추가 되어 있습니다.

이것은 만약 html안에 이미 포맷팅한 정보를 가지고자 할때 Ajax.Updater 클래스를

사용하여 쉽게 채우고자 하는 위치point입니다

 

클라이언트에서 서버 에러들을 다루는 것이 어떻게 가능한지 보기 위해 코드를 조금 변경해보자.

 

<script>
    function getHTML()
    {
      var url = 'http://yourserver/app/getSomeHTML';
      var pars = 'someParameter=ABC';
      var myAjax = new Ajax.Updater(
          {success: 'placeholder'},
           url,{ method: 'get',parameters: pars,onFailure: reportError});
     }

    function reportError(request)
   {
      alert('Sorry. There was an error.');
   }
</script>

<input type=button value=GetHtml onclick="getHTML()">

<div id="placeholder"></div>

위코드는에서는 앞서의 함수에서 보다 호출을 위해 더 많은 옵션을 추가하고 에러 상황을 뽑아내기 위해 함수를 명시하였습니다.(이것은 onFailure옵션을 사용하여 수행한다).

또한 성공적으로 수행된 경우에만 활성화될 묶음자(placeholder)를 명시하였습니다.

 

첫번째 인자는 두가지 프로퍼티(success/failure)를 가지는데 위에서는 failure 프로퍼티를 사용하지 않고 onFailure옵션에서 reportError함수를 사용하여 에러상황을 표시하도록 하였습니다.

 

url로 호출된 서버 로직에서 HTML 대신에 자바스크립트 코드를 반환한다면, Ajax.Updater객체는 자바스크립트 코드가 될수 있습니다. 자바스크립트로 응답을 처리하기 위한 객체를 얻기 위해서는  객체 생성자의 마지막 인자에 evalScripts: true; 옵션을 추가하기만 하면 된다

.

좀더 상세한 설명을 원하신다면, Ajax.Request 참조문서와 Ajax.options 참조문서를 참조하세요.

 

Prototype.js 가이드 01

WEB2.0/ajax | 2006. 5. 10. 11:32
Posted by 시반

Prototype은 무엇인가.?

prototype.jsSam Stephenson에 의해 작성된 자바스크립트 라이브러리이며 웹2.0의 특성에 따라 작성된 코드들은 비동기적 웹페이지 구현시 많은 도움을 줄 수 있을 것입니다

 

 

ProtoType의 사용

 

prototype은 http://prototype.conio.net/에서 다운 받을 수 있으며 구현하고자 하는 페이지에서 다음과 같은 구문을 추가하면 prototype framework를 사용할 수 있다

 

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

라이브러리를 사용하는 것은 반복적인 타이핑과 어구를 많이 줄일수 있게 됨으로서 작업 생산성 및 효율성을 높이는 데 있다

당연히 prototype.js에도 미리 정의된 많은 수의 객체와 유틸리티 함수를 가지게 되는데 어떤 것들이 있는지 살펴보도록 한다

 

유틸리티 함수들(utility functions)

 

$() 함수 사용하기

$()함수는 가장 많이 사용되는 DOM의 document.getElementById()함수에 대한 편리한 단축키라고 할 수 있다. 예를 들면 DOM함수를 통해 특정id를 가진 요소 하나를 가져온다고 하자

 

 node = document.getElementById("elementID");

 

위의 식은 $()를 사용하여 다음과 같이 바꿀수 있다 

 

 node = $("elementID"); 

 

하지만 $()함수는 DOM함수와는 달리 여러개의 id를 사용할수 있다는 장점이 있다 이 때 반환하는 값은 Array객체를 반환한다

 

 allNodes = $("firstDiv", "secondDiv");

 

 for(i = 0; i < allNodes.length; i++) {

    alert(allNodes[i].innerHTML);

 }

 

이 함수의 또 다른 장점은 이 함수를 통하여 id문자열이나 요소객체 자체를 전달할 수 있기

때문에 인자타입을 가지는 다른 함수를 생성할때 매우 유용하다

$F() 함수 사용하기

$F() 함수는  DOM의 document.getElementById()함수에 대한 또 다른 단축키라 할 수 있다.

이것은 text박스나 드랍다운 list와 같은 어떤 필드의 입력 컨트롤의 값을 반환한다. 

마찬가지로 요소 id나 요소객체 자체를 인자로 가질수 있다.

 

예를 들면 다음과 같은 Form필드가 존재한다고 하자

 <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("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

 

$F()을 통해 쉽게 입력컨트롤의 값을 쉽게 가져올 수 있지만

라디오그룹에서는 사용하기 힘들다는 점과 $()와 같이 다수의 인자를 가질수 없다

$A() 함수 사용하기

$A() 함수는 인자들을 하나의 인자로 받아들여 Array객체로 변환한다

 

Array Class상속을 겸한 이 함수는 어떠한 enumerable list 형태도 Array객체로 변환 또는 복사 할 수 있다는 장점이 있다

예를 들면 다음과 같이 DOM의 NodeLists를 regular Arrays로 변환하기에 유용하다 

 <script>
    function showOptions() {
      var someNodeList = $('lstEmployees').getElementsByTagName('option');
      var nodes = $A(someNodeList);
      nodes.each(function(node) {
                         alert(node.nodeName + ': ' + node.innerHTML);
                       });
    }
 </script>
 
 <select id="lstEmployees" size="10" >
   <option value="5">Buchanan, Steven</option>
   <option value="8">Callahan, Laura</option>
   <option value="1">Davolio, Nancy</option>
 </select>
 
 <input type="button" value="Show the options" onclick="showOptions();">

 

 

$A() 의 또 하나의 장점은 함수생성시 인자의 수를 유연하게 받아들이게 한다는 점이다

 <script>

   function shoutOut(){

       sayHi('Hello, ', 'Homer', 'Bart', 'Marge', 'Snowball');

   }

 

   function sayHi(){

      var names = $A(arguments).slice(1);

      var phrase = arguments[0];

      for(i=0; i<names.length; i++)

          alert(phrase + names[i]);

   }

 </script>

 <input type="button" value="Say hi to everybody" onclick="shoutOut();" >

$H() 함수 사용하기

$H() 함수는 결합된 배열처럼 보이는 Hash객체로 변환한다.

 <script>

    function testHash() {

        var a = []; //let's populate the associative array

        a['first'] = 10;

        a['second'] = 20;

        a['third'] = 30;

 

        //now transform it into a hash

       var h = $H(a);

       alert(h.toQueryString());

       //displays: first=10&second=20&third=30 }

 </script>

$R() 함수 사용하기

$R() 함수는 new ObjectRange(lowerBound, upperBound, excludeBounds) 형태의 다른 표현이다. 이 클래스에 대하여는 ObjectRange 클래스 문서를 통해 확인해보시길 바라며. 다음은 each 메소드를 통해 반복(iterators)의 사용법을 보여주는 간단한 예제입니다.

더 많은 메소드는 Enumerable 클래스 문서에서 보실 수 있습니다.

 <script>

    function demoDollar_R()

    {

       var range = $R(10, 20, false);

       range.each(function(value, index)

                         { alert(value); });

     }

 </script>

 <input type="button" value="Sample Count" onclick="demoDollar_R();" >

Try.these() 함수 사용하기

Try.these()함수는 개발자가 across Browser구현시 서로 다른 javascript등을 작성할 필요가 있는 코드생성시 도움을 주는 중요한 함수입니다

이 함수는 인자처럼 많은 수의 함수를 가지고 그것들을 순차적으로 호출하도록 해준다. 이것은 함수중에 하나씩 수행하고 성공적인 함수호출의 결과를 반환할때까지 순차적으로 수행된다.

 <script>

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

 </script>

 

 <input type="button" value="Try_these_test" onclick="test();" >

 

[웹 2.0은 없다] 오래된 미래 이야기

WEB2.0 | 2006. 5. 8. 15:05
Posted by 시반
웹 2.0 열기가 뜨겁다. 닷컴이 지나온 긴 터널을 생각하면 모처럼의 활기가 나쁠리 없다. 미국뿐 아니라 우리나라에도 앵콜을 하는 컨퍼런스가 있는 가하면 일반 언론들까지 웹 2.0을 다루는데 가세했다. 아직은 미국 이야기지만 관련 업체에 대한 투자나 인수합병 열기도 뜨겁다. 하지만 다른 한쪽에서는 '컨퍼런스'가 최고의 수익 모델인 ‘거품 2.0(Bubble 2.0)’이라거나, 업체들이 자신을 포장하는데 써먹는 마케팅 용어일 뿐이라는 비판도 만만치 않다.

이런 갑론을박 속에서 사람들을 혼란스럽게 하는 것은 사실 아주 근본적인 질문이다.

“도대체 웹 2.0이란 무엇인가?”

대답이 길어지는 것은 언제나 분명한 답이 없기 때문이다. 하지만 언제까지 남의 용어를 빌려서 길잡이를 삼고, 그 다음이 어떻게 펼쳐질지 말해주기만 기다리면서 여행을 떠날 수는 없다. 누구나 자신만의 대답을 가져야 한다. 그래서 필자는 부족하지만 지난 2월 15, 16일 웹 2.0 컨퍼런스에서 나름의 대답을 시도했다. 그리고 그 내용을 기반으로 다시 글을 쓰려고 한다. 물론 이것만이 정답이라고 주장할 수는 없다. 하지만 필요한 분들이 좋은 답을 찾아가는 데 작은 디딤돌이 될 수 있기를 바란다.

웹 2.0 혹은 오래된 미래

웹 2.0에 대한 여러가지 정의를 듣다 보면, 노자가 도덕경 첫머리에서 말했던 "도가도비상도, 명가명비상명 (道可道非常道, 名可名非常名)"이라는 말이 생각난다. 월드 와이드 웹이라는 것도 정의 내리기 어려운데 ‘2.0’이라는 말까지 붙었으니 뭔가 그럴듯해 보이는 것은 분명하다. 하지만 막상 사업이나 서비스에 적용하려고 하면 손에 잡히지 않는다. 사실 이런 '화두'식의 접근은 말을 잘 고르면 수많은 후발 논쟁을 불러일으키면서 처음 말한 사람(들)을 구름위에 올려놓는 경향이 있다.

웹 2.0은 누가뭐래도 용어 선택의 승리다. 차세대 웹이나 시멘틱 웹 같은 말이었다면 이런 반향을 일으키지 못했을 것이다. 또한 팀 오라일리의 생각과 달리 분명히 마케팅적이기도 하다. 사람들을 움직이는 힘이 있기 때문이다. 의식적이든 무의식적이든 '참여', '공유', '사람' 같은 광고 캠페인 용어들까지 전면에 배치되어 있다. 모호한 희망이 짙게 배어있다. 이렇다보니 "어떻게 적용하나?"나 "수익모델은?" 같은 질문에 곧바로 대답이 나오기 어려울 수 밖에 없다.

하지만 그럼에도 불구하고 웹 2.0은 잠깐 지나갈 유행으로 넘기기에는 의미가 너무 크다. 어떤 분들의 말처럼 차세대 웹이라서가 아니다. 오히려 웹의 본질을 짚어내고 있기 때문이다. 우선 웹 2.0이라는 말이 등장하게 된 배경부터 그렇다.

이 개념은 2004년 미국의 한 컨퍼런스에서 브레인스토밍을 하면서 시작되었다. 닷컴 거품이 붕괴된 후에도 살아남아서 발전하고 있는 구글이나 아마존 같은 기업들의 공통점을 찾던 것이 출발이었다. 마치 스티븐 코비가 200년 간의 성공 관련 문헌을 조사해서 '성공하는 사람들의 7가지 습관'을 정리한 것과 같은 방식이다. 따라서 웹 2.0은 '살아남은 닷컴 기업들의 7가지 원칙'이라고도 할 수 있다. 우연히도 오라일리 역시 7가지를 정리했다.

1. 웹은 플랫폼이다. (The Web As Platform)
2. 집단지성을 활용한다. (Harnessing Collective Intelligence)
3. 데이터가 차별화의 열쇠다. (Data is the Next Intel Inside)
4. 소프트웨어 배포 주기란 없다. (End of the Software Release Cycle)
5. 가볍고 단순하게 프로그래밍한다. (Lightweight Programming Models)
6. 소프트웨어는 PC에 얽매이지 않는다.
(Software Above the Level of a Single Device)
7. 사용자들에게 더 많은 편리함을 제공한다. (Rich User Experiences)

몇몇 선구자들이 웹의 기초를 설계했지만 사실 그것이 어떤 파장을 일으킬지는 완전히 알지 못했다.(각주 1) 사람들은 웹에 자신들이 참여한 지 10년이 지난 후에야 비로소 웹이 어떻게 작동하는 세상인지 알게되었다.(각주 2) 웹 2.0이란 웹의 업그레이드가 아니라 '웹(과 사람에 대한 이해) 2.0'이다. 웹 2.0이 중요한 것은 새로워서가 아니라 '웹은 이렇게 돌아가고 이렇게 활용한다'는 원칙과 깊은 관계가 있기 때문이다. 자주 언급되는 RSS나 꼬리표(tag)같은 기술 역시 실상은 그 본질을 담고 연결하는 도구라고 할 수 있다.

각주
(1) 철학이 기술을 만들고 기술은 문화를 만든다. 철학이 없다면 창조할 수 없다. 메뉴얼만 읽으며 허둥거릴 뿐이다.

(2) 월드와이드웹이 세상에 공개된 것은 1991년이다. 하지만 대중에게 알려지기 시작한 것은 1993년 모자이크 브라우저가 등장하고 1994년 검색엔진 서비스가 등장하면서 부터였다. 웹 2.0 논의가 시작된 해(2004년)는 사람들이 웹에 참여하고서 10년을 보낸 후였다.

그 뿐 아니다. 웹 2.0이 지향하는 '열린 네트워크를 통한 거대한 협력 시스템'은 어느 날 갑자기 등장한 것이 아니다. 1997년에 나온 에릭 레이몬드의 '성당과 시장(The Cathedral and the Bazaar)'에서도 발견할 수 있다. 리눅스와 오픈 소스 프로젝트의 원칙을 정리한 이 기념비적인 문서는 너무나 웹 2.0스럽다!

"일찍 발표하고 자주 발표하며, 할 수 있는 모든 것을 위임하고, 뒤범벅이 된 부분까지 공개하는, 리누스 토발즈의 개발 스타일은 놀라울 뿐이었다."

양쪽의 차이는 생각보다 많지 않다. 성당과 시장이 프로그래머라는 특정 집단이 서로 협력하면서 응용 프로그램을 개발하는 방식이라면, 웹 2.0은 더 넓게 확장되어 일반 사용자들이 웹 서비스 위에서 다양하게 협력하는 것이다. 영역은 다르지만 근본 마인드는 같다. 성당과 시장의 주장 몇가지를 웹 2.0의 눈으로 살펴보자.

성당과 시장 웹 2.0
"사용자는 공동 개발자다." 플리커, 위키피디어 등에서 사용자는 공동 편집자다.
"일찍 발표하고 자주 발표한다." 끊없는 베타(Perpetual Beta) 서비스가 되어야 한다.
"자료 구조를 훌륭하게 만든다." 참여와 공유를 뒷받침하는 아키텍쳐가 필요하다.
"완벽함은 더 이상 버릴 게 없는 상태를 말한다." 단순하고 모듈화 된 프로그래밍을 한다.
"기존 것을 재사용한다." 에이잭스(AJAX)는 신기술이 아니라 신조합이다.


웹 2.0은 오래된 미래다. 역사에서 찾은 미래이며, 본질에서 찾은 성공 전략이다.(각주 3) 피터 드러커는 인터넷 혁명을 전망하기 위해 철도 혁명을 되돌아 보았다.(각주 4) 마케팅 전문가인 알 리스는 "미래를 예측하는 유일한 방법은 과거를 연구하는 것"이라고 했다. 웹 2.0을 신기술이나 새로운 혁명으로만 포장한다면 결국 또 한번의 실망으로 끝날 것이다.

각주
(3) 웹 2.0이 궁긍적으로 건드리는 영역은 너무나 사회적이고 철학적이다. 꼬리에 꼬리를 문다면 알렉산드리아 도서관이나 가인과 아벨 이야기까지 거슬러 올라가야 할지도 모른다.

(4) 인간의 활동 영역이 확장되었다는 점에서 인터넷 혁명과 철도 혁명은 같은 맥락에 있다.


웹의 미래를 보기 위해 본질로 눈을 돌려야 한다. 그 본질의 물꼬를 터주는 기술과 서비스를 지향해야 한다. 또한 웹 2.0이란 단어에 묶여 있을 필요도 없다. 그 단어는 불 붙이는 일로 생을 다하는 점화용 화두에 불과하다. 언덕 너머 세상은 팀 오라일리와 친구들 역시 알지 못한다.

부디 웹 2.0 논의가 짧은 욕심에 파묻히지 않고 웹다운 웹이 발전하는 전기가 되기를 바란다.

출처 : ZDNet

'WEB2.0' 카테고리의 다른 글

웹 개발 패러다임의 전환 - Flex와 Ajax의 동거  (0) 2007.01.18
개발자의 새로운 키, 웹2.0  (0) 2006.08.25
HTML의 미래, Part 1: WHATWG  (0) 2006.06.02
Web 2.0, Lesson for Success  (0) 2006.05.08
WEB 2.0 잘못 바라보기  (0) 2006.04.24
 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)