ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Ajax 기본 강의 문서.
    Programming/AJAX 2011. 3. 2. 22:34
     

     Ajax 기본개념

    • 자바스크립트 기본 문법

    • 간단한 HTML과 CSS

    • DHTML (Dyanmic HTML), DOM(DocumentObjectModel)

    • Ajax (XMLHttpRequest)

    • JavaScript Framework

      • prototype

      • script.aculo.us

    예제를 통해서 다루게 되는 Ajax 응용 기술

    • 동적인 테이블 제어

    • HTML 대화상자 기능

    • 검색어 추천 기능

    • 트리 폴딩

    • 드래그 & 드랍

    실습 내용

    DHTML

    DHTML(Dynamic HTML) 기초

    링크를 누르면 특정 태그 안의 내용을 바꾼다. document.getElementById를 이용해서 특정 id를 가진 엘리먼트를 취하고 innerHTML 속성을 통해서 엘리먼트의 내용을 변경한다.

    <a href="#" onclick="document.getElementById('greeting').innerHTML += ' Hello'">Greeting!!</a>
    <p id="greeting">Hello</p>

    DHTML 테이블 조작

    DOM을 이용해서 테이블에 동적으로 내용을 추가한다. document.createElement를 이용해서 새로운 엘리먼트를 만들고 부모 엘리먼트의 appendChild를 이용해서 만든 엘리먼트를 추가할 수 있다. 내용은 역시 innerHTML로 조정할 수 있다.

    <script type="text/javascript">
    function appendNewElement(parent, elementName, text) {
    var child = document.createElement(elementName)
    child.innerHTML = text
    parent.appendChild(child)
    }

    function addRow(form) {
    var tr = document.createElement('tr')

    appendNewElement(tr, 'td', form.title.value)
    appendNewElement(tr, 'td', form.price.value)
    appendNewElement(tr, 'td', form.sold.value)

    document.getElementById('tbody').appendChild(tr)
    return false;
    }
    </script>

    <form onsubmit="return addRow(this);">
    <input type="text" name="title">
    <input type="text" name="price">
    <input type="text" name="sold">
    <input type="submit" value="목록 추가">
    </form>
    <table>
    <thead>
    <tr>
    <th>도서명</th>
    <th>가격</th>
    <th>판매량</th>
    </tr>
    </thead>
    <tbody id="tbody">
    <tr>
    <td>Head Rush Ajax</td>
    <td>22000</td>
    <td>180</td>
    </tr>
    <tr>
    <td>Ajax in Action</td>
    <td>28000</td>
    <td>70</td>
    </tr>
    <tr>
    <td>Ajax Hacks</td>
    <td>25000</td>
    <td>80</td>
    </tr>
    </tbody>
    </table>

    DHTML 대화상자

    DHTML에서는 style도 바꿀 수 있다. CSS style의 display 속성을 block/none으로 바꾸면 특정 엘리먼트의 표시 여부를 변경할 수 있으므로 이걸 이용해서 HTML 내에서 대화상자를 구현할 수 있다.

    <script type="text/javascript">
    function showDialog() {
    document.getElementById('dialog').style.display = 'block'
    }
    function hideDialog() {
    document.getElementById('dialog').style.display = 'none'
    }
    </script>

    <a href="#" onclick="showDialog()">대화상자 띄우기</a>
    <a href="#" onclick="hideDialog()">대화상자 감추기</a>

    <div id="dialog" style="display: none;">
    대화상자가 잘 보이나요?
    </div>

    Ajax

    Ajax 기초

    XMLHttpRequest를 이용해서 동적으로 페이지의 내용을 업데이트한다.

    <a href="#" onclick="request()">Hello!</a>
    <div id="message" style="position:absolute; left: 300px; right: 300px; width: 200px; height: 100px; border: 1px solid black">

    var req;
    function request() {
    req = new XMLHttpRequest()
    req.open("GET", "hello.txt", true);
    req.onreadystatechange = showMessage
    req.send(null);
    }
    function showMessage() {
    if (req.readyState != 4) return
    document.getElementById('message').innerHTML = req.responseText
    }

    prototype 이용

    script 부분을 prototype을 이용해서 좀더 쉽게 구현할 수 있다.

    function request() {
    new Ajax.Request('hello.txt', {
    method: 'get',
    onSuccess: showMessage
    })
    }
    function showMessage(req) {
    $('message').innerHTML = req.responseText
    }

    prototype Ajax Updater

    function request() {
    new Ajax.Updater('message', 'hello.txt')
    }

    JavaScript Framework 소개

    JavaScript

    • function 대입 가능

      • function add(a, b) {
        return a + b
        }

        func = add
        alert(func(3, 5))
    • prototype ${}

      • <form>
        <label for="fruit">fruit</label>
        <input id="fruit" type="text" name="fruit" value="apple"/>
        <label for="buy">buy</label>
        <input id="buy" type="checkbox"/>
        </form>
        <a href="javascript:alert($('fruit').value)">show fruit name</a>
        <a href="javascript:alert($('buy').checked)">show buy checked?</a>
    • dialog using $(), css

      • <div id="dialog" style="display: none; position: absolute; left:200px; top:200px; background-color: #E0F0E0">
        안녕하세요
        </div>
        <a href="#" onClick="$('dialog').style.display=''">show</a>
        <a href="#" onClick="$('dialog').style.display='none'">hide</a>
    • 객체는 Map(혹은 Dictionary) 형태의 자료구조로도 활용 가능하다.

      • var apple = {name:'apple', price:500};
        var banana = {name:'banana', price:100};
        alert(apple.name)
        alert(banana.price)
    • 배열 사용법

      • var apple = {name:'apple', price:500};
        var banana = {name:'banana', price:100};
        var kiwi = {name:'kiwi', price:1000};
        var orange = {name:'orange', price:1500};

        var fruits = [apple, banana, kiwi, orange]

        for (var i = 0; i < fruits.length; i++) {
        alert(fruits[i].name)
        }
    • prototype each로 for loop 개선하기

      • <div id="result">
        </div>
        <script type="text/javascript">
        var apple = {name:'apple', price:500};
        var banana = {name:'banana', price:100};
        var kiwi = {name:'kiwi', price:1000};
        var orange = {name:'orange', price:1500};

        var fruits = [apple, banana, kiwi, orange]

        fruits.each(function(element, index) {
        $('result').innerHTML += '[' + index + ']' + element.name + '<br/>'
        });
        </script>
    • prototype each의 구현이 어떻게 되어 있나

      • var Enumerable = {
        each: function(iterator) {
        var index = 0;
        try {
        this._each(function(value) {
        try {
        iterator(value, index++);
        } catch (e) {
        if (e != $continue) throw e;
        }
        });
        } catch (e) {
        if (e != $break) throw e;
        }
        },
        ...
        }

        Object.extend(Array.prototype, Enumerable);
    • 이미 존재하는 객체에 속성 추가하기

      • var obj = new Object()
        obj.hello = function() {
        alert('Hello World')
        }
        obj.hello()
    • 위의 기능을 활용한 Object.extend

      • Object.extend = function(destination, source) {
        for (property in source) {
        destination[property] = source[property];
        }
        return destination;
        }
    • Array.prototype을 통해서 prototype에 대한 설명

      • Array.prototype.alertLength = function() {
        alert(this.length)
        }
        var array = [1, 2, 3, 4]
        array.alertLength()
    • 위로 돌아가서 each의 구현 다시 설명

    응용 예제

    검색어 추천 기능

    script.aculo.us

    자바스크립트 프레임웍인 script.aculo.us를 이용한 검색어 추천 기능.

    <form>
    <input type="text" id="query" length="60"/>
    <div id="keywords" style="display:none;"></div>
    </form>
    <script type="text/javascript">
    var keywordList = ['ABBA', 'AC/DC', 'Aerosmith', 'America', 'Bay City Rollers', 'Black Sabbath', 'Boston', 'David Bowie', 'Can', 'The Carpenters', 'Chicago', 'The Commodores', 'Crass', 'Deep Purple', 'The Doobie Brothers', 'Eagles', 'Fleetwood Mac', 'Haciendo Punto en Otro Son', 'Heart', 'Iggy Pop and the Stooges', 'Journey', 'Judas Priest', 'KC and the Sunshine Band', 'Kiss', 'Kraftwerk', 'Led Zeppelin', 'Lindisfarne (band)', 'Lipps, Inc', 'Lynyrd Skynyrd', 'Pink Floyd', 'Queen', 'Ramones', 'REO Speedwagon', 'Rhythm Heritage', 'Rush', 'Sex Pistols', 'Slade', 'Steely Dan', 'Stillwater', 'Styx', 'Supertramp', 'Sweet', 'Three Dog Night', 'The Village People', 'Wings (fronted by former Beatle Paul McCartney)', 'Yes']
    new Autocompleter.Local('query', 'keywords', keywordList, {})
    </script>

    직접 구현하기

    이벤트를 잡아서 DOM 조작을 통해 검색어 자동완성을 직접 구현

    var keywords = ['ABBA', 'AC/DC', 'Aerosmith', 'America', 'Bay City Rollers', 'Black Sabbath', 'Boston', 'David Bowie', 'Can', 'The Carpenters', 'Chicago', 'The Commodores', 'Crass', 'Deep Purple', 'The Doobie Brothers', 'Eagles', 'Fleetwood Mac', 'Haciendo Punto en Otro Son', 'Heart', 'Iggy Pop and the Stooges', 'Journey', 'Judas Priest', 'KC and the Sunshine Band', 'Kiss', 'Kraftwerk', 'Led Zeppelin', 'Lindisfarne (band)', 'Lipps, Inc', 'Lynyrd Skynyrd', 'Pink Floyd', 'Queen', 'Ramones', 'REO Speedwagon', 'Rhythm Heritage', 'Rush', 'Sex Pistols', 'Slade', 'Steely Dan', 'Stillwater', 'Styx', 'Supertramp', 'Sweet', 'Three Dog Night', 'The Village People', 'Wings (fronted by former Beatle Paul McCartney)', 'Yes']
    var count = 0
    var index = -1
    var query = ''
    function suggest() {
    var keyword = $('query').value
    if (keyword == '' || query == keyword) return
    query = keyword

    var suggestHTML = ''
    count = 0

    keywords.each(function(value) {
    if (value.indexOf(keyword) == 0) {
    var attr = ''
    if (count == index) {
    attr = 'class="selected"'
    }
    suggestHTML += '<li ' + attr + '>' + value + '</li>'
    count ++
    }
    })
    $('keywords').innerHTML = suggestHTML
    }

    function choose(event) {
    if (count == 0) return true;

    if (event.keyCode == Event.KEY_UP) {
    index = (index + 3) % count
    } else if (event.keyCode == Event.KEY_DOWN) {
    index = (index + 1) % count
    } else if (event.keyCode == Event.KEY_RETURN) {
    $('query').value = $('keywords').getElementsByTagName('li')[index].innerHTML
    } else {
    return true
    }
    query = ''
    return false;
    }

    window.setInterval(suggest, 100)

    <form onsubmit="return false;">
    <input type="text" id="query" length="60" onkeydown="return choose(event)" />
    <div>
    <ul id="keywords" >
    </ul>
    </div>
    </form>

    트리

    <ul id="tree">
    <li id="search"><span>+ </span>검색</li>
    <li id="community"><span>+ </span>커뮤니티</li>
    <li id="shopping"><span>+ </span>쇼핑</li>
    </ul>
    <script type="text/javascript">
    var treeData = {
    search: [{key:'google', name: '구글'}, {key:'naver', name: '네이버'}, {key:'yahoo', name: '야후'}],
    community: [{key:'cyworld', name: '싸이월드'}, {key:'daumcafe', name: '다음 까페'}],
    shopping: [{key:'openmarket', name: '오픈 마켓'}, {key:'shoppingmall', name: '쇼핑몰'}],
    openmarket: [{key:'gmarket', name: 'G 마켓'}, {key:'auction', name: '옥션'}, {key:'ebay', name: '이베이'}],
    shoppingmall: [{key:'cjmall', name: 'CJ Mall'}, {key:'amazon', name: '아마존'}]
    }

    $$('#tree span').each(function(element) {
    Event.observe(element, 'click', toggle)
    })

    function toggle(event) {
    var element = Event.element(event).parentNode
    if (element.expanded) {
    fold(element)
    element.expanded = false
    } else {
    expand(element)
    element.expanded = true
    }
    }

    function expand(element) {
    var ul = document.createElement('ul')
    element.appendChild(ul)
    var children = treeData[element.id]
    children.each(function(child) {
    var li = document.createElement('li')
    ul.appendChild(li)
    li.id = child.key
    li.innerHTML = '<span>+ </span>' + child.name
    Event.observe(li.firstChild, 'click', toggle)
    })
    element.firstChild.innerHTML = '- '
    }

    function fold(element) {
    element.removeChild(element.getElementsByTagName('ul')[0])
    element.firstChild.innerHTML = '+ '
    }
    </script>

    드래그 & 드랍

    마우스 이벤트와 CSS style의 위치 지정 기능을 이용해서 드래그 & 드랍을 구현할 수 있다.

    function showDialog(){
    $("dialog").style.display='block';
    }
    function hideDialog(){
    $("dialog").style.display='none';
    }

    var posX;
    var posY;

    function setPosition(e){
    if(!e){
    e = window.event
    posX = e.x
    posY = e.y
    }else{
    posX = e.clientX
    posY = e.clientY
    }
    }

    function dragBegin(e){
    setPosition(e)

    $('dialog').startx = posX
    $('dialog').starty = posY
    $('dialog').dragging = true

    }
    function drag(e){
    setPosition(e)

    if ($('dialog').dragging) {

    $('dialog').style.left = $('dialog').offsetLeft + (posX - $('dialog').startx)
    $('dialog').style.top = $('dialog').offsetTop + (posY - $('dialog').starty)
    $('dialog').startx = posX
    $('dialog').starty = posY
    }

    }
    function dragEnd(e){
    $('dialog').dragging = false
    }

    function init(){
    document.onmousemove = drag;
    document.onmouseup = dragEnd;
    $('dialog').onmousedown = dragBegin;
    }

    <div id="dialog" style="position: absolute; left: 300px; top: 200px; width: 300px; border: 1px solid black"  >
    <table cellspacing="0" cellpadding="0" border="0" style="margin-top: 2px;">
    <tbody>
    <tr>

    <td><img border="0" align="absmiddle" style="margin-bottom: 2px;" src="http://imgnews.naver.com/image/news/2006/reply/memo/n1_07.gif"/> </td>
    <td style="padding-top: 2px;">TestTestTest</td>
    </tr>
    </tbody>
    </table>

    참고자료

    문서

    Tools

Designed by Tistory.