■ Front-End ■/JavaScript

[JavaScript] 프로 자바스크립트 테크닉 (5장 ~ 6장) - 2/4

한길(One Way) 2023. 3. 2.

개요

jQuery를 만든 존 레식이 집필한 "Pro JavaScript Techniques"의 번역한 서적이다. JavaScript가 같고 있는 특성을 기준으로 객체지향적인 요소에 대해서 잘 설명하고 있다. jQuery의 기본적인 기술을 확인해 볼 수 있다.

 

책 소개

자바스크립트를 한동안 다뤘던 개발자라면 아는 기본적인 문법이나 문장 구조 같은 기본적인 사항들을 배제하고곧바로 자바스크립트에서의 객체지향이라는 개념과 테스트를 위한 도구배포와 브라우저 지원에 대한 주의사항 등 현대적인 자바스크립트 개발에 필요한 기술들을 실용적인 예와 소스코드를 통해 설명한다.

 

자바스크립트로 개발해 본 사람이라면 누구나어떻게 해야 더 깔끔하고 사용하기 쉬운 코드를 작성할 수 있을지객체지향 언어답게 자바스크립트를 사용하는 방법은 무엇인지 고민했을 것이다내가 개발한 애플리케이션을 테스트할 적절한 도구는 없는지배포 전에 주의해야 할 사항은 없는지혹시 내가 테스트하지 못한 브라우저에서 오류가 발생하는 건 아닌지 걱정했을 수도 있다.

 

이 책은 자바스크립트를 한동안 다뤘던 개발자라면 이미 알고 있을 기본적인 문법이나 문장 구조 같은 기본적인 사항들을 배제하고곧바로 자바스크립트에서의 객체지향이라는 개념과 테스트를 위한 도구배포와 브라우저 지원에 대한 주의사항 등 현대적인 자바스크립트 개발에 필요한 기술들을 실용적인 예와 소스코드를 통해 설명한다.

 

이 책의 저자인 존 레식(John Resig)최근 주목받는 라이브러리인 jQuery를 개발한 자바스크립트 전문가이기도 하며그 경험을 살려 라이브 블로깅(Live Blogging)이나 끝이 없는 블로그(Never-Ending Blog) 같이 실무에 바로 적용할 수 있는 예들도 이 책에서 선보였다.

 

이 책을 읽은 독자라면 자신만의 라이브러리를 구축할 수 있을 정도의 도구들을 얻게 될 뿐만 아니라현대적인 기술로 무장한 자바스크립트 전문가가 될 수 있을 것이다.

 

저자

존 레식 (John Resig)

소개자바스크립트 프로그램 언어에 열정을 품은 프로그래머이며 기업가다자바스크립트 라이브러리인 jQuery의 창시자이자 jQuery의 리드 개발자(lead developer)이고, 2008년 현재 웹을 기반으로 하는 다른 많은 프로젝트에서도 리드 개발자로 활동한다.

 

5장 문서 객체 모델

    모든 최신 브라우저는 DOM을을 기본 지원하며, HTML문서를 나타내는 내부 DOM표현도 지원한다.

 

5.1 문서 객체 모델에 대한 소개

    DOM W3C에서 제정한 XML 문서를 표현하기 위한 표준이다.

    DOM 직관적으로 XML 계층구조를 탐색할 수 있는 방법을 제공하기 위해 만들어졌다.

 

5.2 DOM 탐색하기

    DOM에서는 XML 구조를 탐색 가능한 트리의 형태로 표현한다.

    모든 XML 문서는 문서 엘리먼트라고 부르는 단일 루트 노드에서 시작한다.

     DOM 노드에는 자신의 친척들(부모자식형제)을 가리키는 포인터들이 있다.

    모든 DOM 노드마다 그 자신의 친척들을 참조할 수 있는 포인터 집합이 존재한다.

 

    Element (nodeType = 1) : 엘리먼트 대부분이 이 타입이다.

    Text (nodeType = 3) : 문서 안에 있는 모든 텍스트가 이 타입이다.

    Document (nodeType = 9) : 문서의 루트 엘리먼트이다.

 

    간단한 DOM 탐색

    function prev( elem ) {
        do {
            elem = elem.previousSibling;
        } while ( elem && elem.nodeType != 1 );
        return elem;
    }
 
    function next( elem ) {
        do {
            elem = elem.nextSibling;
        } while ( elem && elem.nodeType != 1 );
        return elem;
    }

    function first( elem ) {
        elem = elem.firstChild;
        return elem && elem.nodeType != 1 ? nextSibling( elem ) : elem;
    }

    function last( elem ) {
        elem = elem.lastChild;
        return elem && elem.nodeType != 1 ? prevSibling( elem ) : elem;
    }

    function parent( elem, num ) {
        num = num || 1;
        for ( var i = 0; i < num; i++ )
        {
            if ( elem != null ) elem = elem.parentNode;
        }
        return elem;
    }

 

    표준 DOM 메서드

    getElementById("everywhere");

    function id(name) {
        return document.getElementById(name);
    }

 

    getElementByTagName("li"); // 배열과 거의 동일한 NodeList 형태로 반환

     function tag(elem,name) {
        return (elem || document).getElementsByTagName(name);
    }

 

5.3 HTML DOM이 로딩되기를 기다리기

    HTML DOM 문서로 작업할 때 발생하는 어려움 중 하나는,

    DOM이 완전히 로딩되기 이전에도 자바스크립트 코드가 실행될 수 있다는 점이다.

 

    브라우저 내부에서 일어나는 순서는 다음과 같다.

    1. HTML을 파싱 한다.

    2. 외부 스크립트나 스타일시트를 로딩한다.

    3. 문서 내의 스크립트를 파싱 하면서 실행시킨다.

    4. HTML DOM이 모두 생성되었다.

    5. 그림과 외부 콘텐츠를 로딩한다.

    6. 페이지 로딩이 끝났다.

 

    헤더에 있는 스크립트와 외부파일의 스크립트는 HTML DOM이 실제로 생성되기 이전에 실행된다.

 

    HTML 문서가 현재 작업 가능한 상태인지 확인하려면 몇 가지를 시험해봐야 한다.

    1. document : 먼저 DOM 문서가 존재하는지 확인해야 한다.

    2. docuemnt.getElementByTagName, document.getElementById 함수가 있는지 확인한다

    3. document.body : 안전을 위하여 body 엘리먼트가 완전히 로딩되었는지 확인하면 좋다.

 

5.4 HTML 문서에서 엘리먼트 찾기

    HTML 문서에서 엘리먼트 찾는 작업과 XML 문서에서 엘리먼트를 찾는 작업은 무척 다르다.

 

    클래스 이름으로 엘리먼트 찾기

    CSS 선택자를 기준으로 엘리먼트 찾기

    cssQuery 딘 에드워즈 (http://dean.edwards.name/my/cssQuery/)

    jQuery 존 레식 (http://jquery.com)

    XPath : XML 문서를 탐색하는 강력한 방법이다.

 

5.5 엘리먼트의 내용 얻기

    모든 DOM 엘리먼트에는 텍스트와 다른 엘리먼트의 혼합물 중 하나를 담을 수 있다.

 

    엘리먼트 내부의 텍스트 얻기

    텍스트를 포함하고 있는 주체는 그 엘리먼트 자체가 아니라 그 자식 텍스트 노드다.

     function text(e) {
        var t = "";
        e = e.childNodes || e;
        for ( var j = 0; j < e.length; j++ )
        {
            t += e[j].nodeType != 1 ? e[j].nodeValue : text(e[j].childNodes);
        }
        return t;
    }

 

    엘리먼트 내부의 HTML 얻기

    모든 HTML DOM 엘리먼트마다 innerHTML이라는이라는 프로퍼티가 추가되어 있다.

    이 프로퍼티에 접근하면 해당 엘리먼트의 HTML 내용을 담고 있는 문자열을 얻는다.

 

5.6 엘리먼트 어트리뷰트 다루기

    function hasAttribute( elem, name ) {
        return elem.getAttribute(name) != null;
    }

 

    어트리뷰트 값을 얻어내거나 설정하기

    안전성을 위하여 항상 일반적인 XML DOM에 호환되는 getAttribue, setAttribute를 쓰라.

    class, for, float, text 같은 단어들이 모두 자바스크립트의 예약어이다.

    className, htmlFor, cssFloat, cssText처럼 변경되어 사용된다.

    function attr(elem, name, value) {
        if ( !name || name.constructor != String ) return '';
        name = { ‘for': 'htmlFor', 'class': 'className' }[name] || name;

        if ( value != null )
        {
            elem[name] = value;

            if ( elem.setAttribute )
                elem.setAttribute(name,value);
        }
        return elem[name] || elem.getAttribute(name) || '';    
    }

 

5.7 DOM 변경하기

    DOM을 변경하는 과정은 세 단계로 나뉜다.

 

    1. 새로운 엘리먼트를 생성하는 방법. DOM을 사용하여 노드를 생성하기

        createElement

        function create( elem ) {
            return document.createElementNS ?
                document.createElementNS( 'http://www.w3.org/1999/xhtml', elem ) :
                document.createElement( elem );
        }

 

    2. 이 엘리먼트를 DOM에 삽입하는 방법. DOM 안에 삽입하기, DOM에 HTML 집어넣기

        insertBefore, appendChild

        function before( parent, before, elem ) {
             if ( elem == null ) {
                elem = before;
                before = parent;
                parent  = before.parentNode;
            }
            parent.insertBefore( checkElem( elem ), before );
        }

        function append( parent, elem ) {
            parent.appendChild( checkElem( elem ) );    
        }

        function checkElem( elem ) {
            // If only a string was provided, convert it into a Text Node
            return elem && elem.constructor == String ?
            document.createTextNode( elem ) : elem;
        }

 

    3. 이 엘리먼트를 제거하는 방법.

        removeChild

        function remove( elem ) {
            if ( elem ) elem.parentNode.removeChild( elem );
        }

        function empty( elem ) {
            while ( elem.firstChild )
                remove( elem.firstChild );
        }

 

6장 이벤트

    무간섭 DOM 스크립팅에서 가장 중요한 측면은 동적으로 등록 또는 해제되는 이벤트이다.

    자바스크립트의 이벤트의 개념은 수년에 걸쳐 진보하면서 지금은 믿고 사용할 수 있을 만하다.

 

6.1 자바스크립트 이벤트에 대한 소개

    자바스크립트의 이벤트는 스레드를 사용하지 않으면서 비동기식으로 작동한다.

    자바스크립트에는 스레드가 존재하지 않는다.

    자바스크립트의 모든 루프는 블로킹 방식이다루프의 실행 중에는 다른 연산이 실행될 수 없다.

    비동기식 콜백을 사용원하는 시점에 실행될 코드에 대한 참조를 제공하면 된다.

    자바스크립트 이벤트는 캡처와 버블이라는 두 단계에 걸쳐 실행된다.

 

6.2 공통적인 이벤트 기능들

    이벤트 처리기의 기본적인 기능 중 하나는 바로 이벤트 객체에 접근할 수 있게 해 준다.

    IE에서는 W3C와와 달리 단 하나의 전역 이벤트 객체만 존재한다.

 

    this 키워드는 단지 편리함을 위해 쓸 뿐이지 그 이상도 그 이하도 아니다.

    this 키워드를 적절히 사용하면 코드를 훨씬 간단하게 작성할 수 있다.

 

    이벤트 버블/캡처를 멈추는 방법은 IE W3C와 다르다.

    function stopBubble(e)
    {
        if ( e )
            e.stopPropagation();
        else
            window.event.cancelBubble = true;
    }

 

    이벤트가 발생할 때 브라우저는 그에 따라 실행되는 기본 동작이 있다.    

    function stopDefault( e ) {
        if ( e ) e.preventDefault();
        return false;
    }

 

6.3 이벤트 리스너 연결하기

    인라인 방식으로 붙이는 방법. <body onload="">

    전통적인 연결 방법. window.onload = function() {}

    DOM 연결: W3C 방법. addEventListener

 

    document.body.addEventListener(keypress, myKeyPressHandler, false);

    window.addEventListener(load, function(){  }, false);

    

    DOM 연결: IE 방법. attachEvent

 

    document.body.attachEvent(onkeypress, myKeyPressHandler);

    window.attachEvent(onload, function(){  });

 

    피터 폴 콕이 2005년 하반기에 콘테스트를 오픈

    딘 에드워즈가 addEvent / removeEvent 라이브러리를 작성 

 

6.4 이벤트의 종류

    마우스 이벤트: mouseover, mouseout, mouseup, mousedown

    키보드 이벤트: keyup, keydown, keypress

    UI 이벤트: focus, blur

    폼 이벤트: submit, change, select

    로딩 이벤트: load, unload

 

6.5 무간섭 DOM 스크립팅

    좋은 코드를 작성하는 데 에너지를 집중하게 해 준다.

    자바스크립트가 비활성화된 상황을 고려

    링크가 자바스크립트에 의존하지 않기

    CSS가 비활성화된 경우에 주의하기 

    이벤트 접근성을 보다 향상하려면 마우스 외의 대안을 함께 제공하는 것을 고려한다

728x90

댓글