[jQuery] 문서 준비 이벤트

문서 준비 이벤트


jQuery(document).ready(function(){ code });

=

jQuery(function(){ code });

=

$(function(){ code });


jQuery에서 문서 준비 이벤트는 웹 브라우저가 HTML의 DOM을 모두 로드할 때를 알려주는 이벤트로, <head> 태그에 jQuery 코드를 삽입할 경우에는 문서 준비 이벤트를 반드시 사용하여야 한다.

<head>에 jQuery 코드를 넣을 때에는 문서 준비 이벤트가 필요하다. 문서 준비 이벤트는 ready이다. HTML을 동적으로 조작하기 위해서는 HTML 문서를 모두 로딩해야만 그 다음에 동작을 가하는 jQuery나 JavaScript 코드가 정상적으로

작동된다. jQuery에는 ready 이벤트와 똑같은 효과를 나타내는 것이 있는데, jQuery() 함수에 매개변수로 직접 함수를 넘겨주면 이 함수는 DOM이 모두 로딩되고 난 후에 실행된다.


※ 문서 준비 이벤트를 사용하지 않은 경우

이 경우에는 <body> 문서의 맨 마지막 </body> 전에 jQuery 코드나 JavaScript 코드를 삽입하면 된다. 왜냐하면 필요한 모든 HTML이 모두 로딩되었고, 그 다음에 동작하는 jQuery 코드가 작동되면서 준비(ready) 이벤트가 필요 없어졌기

때문이다.

따라서 <body> 태그 내부에 <script> 내부에는 문서 준비 이벤트가 필요없다.



'WebFont-end > jQuery' 카테고리의 다른 글

[jQuery] Ajax 설정  (0) 2015.01.11
[jQuery] Ajax 기초  (0) 2014.12.07
[jQuery] Chain  (0) 2014.12.07
[jQuery] Animation  (0) 2014.12.07
[jQuery] Effects  (0) 2014.12.07

[jQuery] Ajax 설정

Ajax 설정


cp.) 요청 매개 변수와 함께 Ajax 요청을 수행한다. data 속성을 사용하면 요청 매개 변수를 쉽게 지정할 수 있다. $ajax() 메서드의 옵션 객체에 url 속성을 입력하고 data 속성에 객체를 입력한다.

ex.) url: 'Home/ActionWithData'.

      data: name:'rintiantta',age:21,  

      success: function(data)

       .......

이렇게 하면 http://localhost:8080/Home/ActionWithData?name=rintiantta&age=21로 

Ajax 요청을 수행한다.


1. $ajax 설정값


(1) url 

HTTP 요청을 할 대상이되는 url

단순히 html 페이지에 대한 주소가 될 수도 있고 WCF.ASMX 서비스에서 노출한 서비스 종단점에 대한 url일 수도 있다.


(2) async

true/false 기본값 true

기본적으로 모든 Ajax 요청은 비동기적으로 보내진다. 동기적으로 호출하면 요청이 진행되는 동안 페이지가 잠시 블록킹된다.


(3) cache

true/false

false로 설정되면 브라우저는 요청된 결과로 받은 페이지를 캐싱하지 않는다.


(4) contentType

기본값: application/x-www-form-urlencode

서버로 데이터를 전송할 때 콘텐츠 타입을 나타내는 값

기본값을 사용하면 대부분의 경우 잘 적용된다. JSON 형식의 데이터를 서버로 보낼 때는 "application/json"으로 설정한다.


(5) type

GET, POST (기본값은 GET이다.)


(6) dataType

서버에서 반환받을 데이터의 타입

사용 가능한 값: html, json, jsonp, script, text

이 값에 따라 반환받은 데이터를 적절하게 자동으로 파싱한다. 이 값을 설정하지 않으면 HTTP 응답의 MIME 타입을 근거로 자동 파싱한다. 만약

xml이 MIME 타입에 포함돼 있다면 xml로 파싱해서 다음 단계로 넘겨준다.


(7) data

서버로 전송될 데이터. GET, POST 같은 전송 타입에 따라 처리되는 방식이 다르다. 어떤 전송 타입이든 ‘키, 값’으로 돼 있어야 한다.

GET 방식이면 key1=value1, key2=value2처럼 구성될 것이고 POST 방식이면서 dataType이 "json" 이면 key1:value1, key2:value2을 전송할 것이다.


(8) processData

true/false

기본적으로 data로 건네받은 객체가 문자열이 아닌 경우는 content-type

이 “application/x-www-form-urlencorded"에 맞게 모두 변경된다.

만약 data에서 넘겨준 그대로를 서버로 보내고 싶다면 false로 지정한다.



2. $ajax() 콜백 설정
$Ajax()는 Ajax 호출을 하는 데 많은 단계를 정의하고 있다. $Ajax() 설정 중에는 이러한 단계별로 호출될 콜백 함수 객체를 전달할 수 있는 항목이 있다. 

(1) beforeSend
beforeSend에 설정된 콜백함수를 호출할 때는 다음의 두 인자를 차례로 전달한다.
jqXHR: jQuery XMLHttpRequest 객체
settings: 설정 항목

(2) dataFilter
서버로부터의 HTTP 요청이 성공하고 나서 서버로부터 데이터를 받으면 호출되는 함수다. success 콜백 함수가 호출되며, 인자로 data, dataType를 받는다.
data: 서버로부터 반환된 raw 데이터
dataType: 호출 시 설정한 dataType 항목의 값 
이 함수는 success로 전달될 데이터를 반환해야 한다.

(3) success
HTTP 요청이 성공하면 호출되는 함수로서, 차례로 data, textStatus, jqXHR를 인자로 전달 받는다.
data: 서버에서 반환된 데이터, dataType 설정에 따라 반환된 결과가 달라진다. json이면 서버에서 반환된 문자열이 JSON.parse()를 거치게 된다.
textStatus: 요청 상태를 나타내는 문자열
jqXHR: JQuery XMLHttpRequest 객체

(4) error
요청이 실패하면 호출될 함수로서, 차례로 jqXHR, textStatus,
errorThrown을 인자로 전달 받는다.
jqXHR: JQuery XMLHttpRequest 객체
textStatus:애러 타입을 나타내는 문자열(‘timeout', 'error', 'abort',
'parseerror' 등)
errorThrown: HTTP 에러가 발생하는 경우 “Not Found"나 
“Internal Server Error”와 같이 HTTP 상태를 나타내는 문자열

(5) complete
HTTP 요청이 끝난 후나 success, error 콜백 함수가 실행되고 나서
호출되는 함수로서, 차례로 jqXHR, textStatus를 인자로 전달 받는다.


'WebFont-end > jQuery' 카테고리의 다른 글

[jQuery] 문서 준비 이벤트  (0) 2015.01.11
[jQuery] Ajax 기초  (0) 2014.12.07
[jQuery] Chain  (0) 2014.12.07
[jQuery] Animation  (0) 2014.12.07
[jQuery] Effects  (0) 2014.12.07

[JavaScript] 이벤트 타입


이벤트 타입


아래는 onclick 이벤트 타입의 예제다. 이벤트 타입이라는 것은 이벤트의 종류라고 할 수 있다. 사용자 정보가 유효한지 여부를 확인하기 위해 이벤트를 많이 사용한다.

<input type="button" onclick="alert(1);" />

웹브라우저는 많은 종류의 이벤트 타입을 제공한다. 하위 토픽에서는 주요한 이벤트 타입을 중심으로 어떤 이벤트 타입이 있는지 알아보겠다.


1. 폼

폼과 관련된 이벤트 타입을 알아보자.


(1) submit

- submit은 폼의 정보를 서버로 전송하는 명령인 submit시에 일어난다.

- form 태그에 적용된다.

아래 예제는 전송 전에 텍스트 필드에 값이 입력 되었는지를 확인한다. 만약 값이 입력되지 않았다면 전송을 중단한다.

<form id="target" action="result.html">

    <label for="name">name</label> <input id="name" type="name" />

    <input type="submit" />

</form>

<script>

var t = document.getElementById('target');

t.addEventListener('submit', function(event){<!-- 첫번째 인자의 이벤트가 발생하면 두번째 인자인 익명함수가 실행된다. -->

    if(document.getElementById('name').value.length === 0){

        alert('Name 필드의 값이 누락 되었습니다');

        event.preventDefault(); <!-- submit이 안 된다.(action 프로퍼티로 전송되는 것을 방지한다.) 기본 동작의 취소-->

    }

});

</script>


(2) change

- change는 폼 컨트롤(value의 값)의 `값이 변경 되었을 때 발생하는 이벤트다.

- input(text,radio,checkbox), textarea, select 태그에 적용된다.

<p id="result"></p>

<input id="target" type="name" />

<script>

var t = document.getElementById('target');

t.addEventListener('change', function(event){

    document.getElementById('result').innerHTML=event.target.value;

});

</script>


(3) blur, focus

- focus는 엘리먼트에 포커스가 생겼을 때(input의 text 프로퍼티 테두리 내부를 클릭했을때), blur은 포커스가 사라졌을 때 발생(input의 text 프로퍼티 테두리 외부를 클릭했을 때)하는 이벤트다. 

- 다음 태그를 제외한 모든 태그에서 발생한다. <base>, <bdo>, <br>, <head>, <html>, <iframe>, <meta>, <param>, <script>, <style>, <title>

<input id="target" type="name" />

<script>

var t = document.getElementById('target');

t.addEventListener('blur', function(event){

    alert('blur');  

});

t.addEventListener('focus', function(event){

    alert('focus'); 

});

</script>


2. 문서 로딩

자바스크립트를 실행할 때 어떤 타이밍에 실행을 해야지만 문서에 있는 엘리먼트에 정확하게 문제없이 명령을 실행하느냐의 문제가 문서 로딩 part에서 다루는 부분이다.

웹페이지를 프로그래밍적으로 제어하기 위해서는 웹페이지의 모든 요소에 대한 처리가 끝나야 한다. 이것을 알려주는 이벤트가 load, DOMContentLoaded이다.

아래 코드의 실행결과는 null이다. <p id="target">Hello</p>가 로딩되기 전에 자바스크립트가 실행되었기 때문이다.

<html>

    <head>

        <script>

        var t = document.getElementById('target');

        console.log(t);

        </script>

    </head>

    <body>

        <p id="target">Hello</p>

    </body>

</html>

실행결과)

null

- null 인 이유: 자바스크립트를 통해서 id값이 target인 엘리먼트를 찾고 있는 시점에서는 p태그가 만들어져 있지 않기 때문이다.

(존재하지 않는 대상에 대해서 참조하려고 했기 때문에 document.getElementById('target')의 리턴값이 null이다.)


이를 해결하기 위한 방법은 아래와 같이 스크립트를 문서 끝에 위치시키는 것이다.(위에서 아래로 순차적으로 로딩된다.)

<p id="target">Hello</p>

<script>

    var t = document.getElementById('target');

    console.log(t);

</script>


또 다른 방법은 load 이벤트를 이용하는 것이다.

<head>

    <script>

        window.addEventListener('load', function(){

            var t = document.getElementById('target');

            console.log(t);

        })

    </script>

</head>

<body>

    <p id="target">Hello</p>

</body>

그런데 load 이벤트는 문서내의 모든 리소스(이미지, 스크립트)의 다운로드가 끝난 후에 실행(onload: 다운로드 끝날때까지 호출되지 않는다.)된다. 이것을 에플리케이션의 구동이 너무 지연되는 부작용을 초래할 수 있다.

DOMContentLoaded는 문서에서 스크립트 작업을 할 수 있을 때 실행되기 때문에 이미지 다운로드를 기다릴 필요가 없다.

<html>

    <head>

        <script>

            window.addEventListener('load', function(){

                console.log('load');

            })

            window.addEventListener('DOMContentLoaded', function(){<!--DOM에 해당하는 Content가 모두 로드 끝난후 발생하는 이벤트-->

                console.log('DOMContentLoaded');

            })

        </script>

    </head>

    <body>

        <p id="target">Hello</p>

    </body>

</html>

DOMContentLoaded 이벤트는 IE9을 포함한 모든 브라우저에서 지원하고 있다.


3. 마우스


(1) 이벤트 타입

웹브라우저는 마우스와 관련해서 다양한 이벤트 타입을 지원한다.

1) click

클릭했을 때 발생하는 이벤트. 

2) dblclick

더블클릭을 했을 때 발생하는 이벤트

3) mousedown

마우스를 누를 때 발생

4) mouseup

마우스버튼을 땔 때 발생

5) mousemove

마우스를 움직일 때

6) mouseover

마우스가 엘리먼트에 진입할 때 발생

7) mouseout

마우스가 엘리먼트에서 빠져나갈 때 발생

8) contextmenu

컨텍스트 메뉴가 실행될 때 발생


(2) 키보드 조합

마우스 이벤트가 호출될 때 특수키(alt, ctrl, shift)가 눌려진 상태를 감지해야 한다면 이벤트 객체의 프로퍼티를 사용한다. 이 때 사용하는 프로퍼티는 아래와 같다.

- event.shiftKey

- event.altKey

- event.ctrlKey


(3)  마우스 포인터 위치

마우스 이벤트와 관련한 작업에서는 마우스 포인터의 위치를 알아내는 것이 중요할 때가 있는데 이런 경우 이벤트 객체의 clientX와 clientY를 사용한다.


(4) 예제

아래 예제는 지금까지 살펴본 이벤트와 관련된 기능을 종합적으로 보여준다. 

<html>

    <head>

        <style>

            body{

                background-color: black;

                color:white;

            }

            #target{

                width:200px;

                height:200px;

                background-color: green;

                margin:10px;

            }

            table{

                border-collapse: collapse;

                margin:10px;

                float: left;

                width:200px;

            }

            td, th{

                padding:10px;

                border:1px solid gray;

            }

        </style>

    </head>

    <body>

        <div id="target">

 

        </div>

        <table>

            <tr>

                <th>event type</th>

                <th>info</th>

            </tr>

            <tr>

                <td>click</td>

                <td id="elmclick"></td>

            </tr> 

            <tr>

                <td>dblclick</td>

                <td id="elmdblclick"></td>

            </tr>

            <tr>

                <td>mousedown</td>

                <td id="elmmousedown"></td>

            </tr>         

            <tr>

                <td>mouseup</td>

                <td id="elmmouseup"></td>

            </tr>         

            <tr>

                <td>mousemove</td>

                <td id="elmmousemove"></td>

            </tr>         

            <tr>

                <td>mouseover</td>

                <td id="elmmouseover"></td>

            </tr>         

            <tr>

                <td>mouseout</td>

                <td id="elmmouseout"></td>

            </tr>

            <tr>

                <td>contextmenu</td>

                <td id="elmcontextmenu"></td>

            </tr>         

        </table>

        <table>

            <tr>

                <th>key</th>

                <th>info</th>

            </tr>

            <tr>

                <td>event.altKey</td>

                <td id="elmaltkey"></td>

            </tr>

            <tr>

                <td>event.ctrlKey</td>

                <td id="elmctrlkey"></td>

            </tr>

            <tr>

                <td>event.shiftKey</td>

                <td id="elmshiftKey"></td>

            </tr>

        </table>

        <table>

            <tr>

                <th>position</th>

                <th>info</th>

            </tr>

            <tr>

                <td>event.clientX</td>

                <td id="elemclientx"></td>

            </tr>

            <tr>

                <td>event.clientY</td>

                <td id="elemclienty"></td>

            </tr>

        </table>

        <script>

        var t = document.getElementById('target');

        function handler(event){

            var info = document.getElementById('elm'+event.type);<!--type프로퍼티로 이벤트 종류를 알 수 있다.-->

            var time = new Date();

            var timestr = time.getMilliseconds();<!--500이면 0.5초 -->

            info.innerHTML = (timestr);

            if(event.altKey){

                document.getElementById('elmaltkey').innerHTML = timestr;

            }

            if(event.ctrlKey){

                document.getElementById('elmctrlkey').innerHTML = timestr;

            }

            if(event.shiftKey){

                document.getElementById('elmshiftKey').innerHTML = timestr;

            }

            document.getElementById('elemclientx').innerHTML = event.clientX;

            document.getElementById('elemclienty').innerHTML = event.clientY;

        }

        t.addEventListener('click', handler);

        t.addEventListener('dblclick', handler);

        t.addEventListener('mousedown', handler);

        t.addEventListener('mouseup', handler);

        t.addEventListener('mousemove', handler);

        t.addEventListener('mouseover', handler);

        t.addEventListener('mouseout', handler);

        t.addEventListener('contextmenu', handler);

        </script>

    </body>

</html>


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트 등록방법  (0) 2014.12.25
[JavaScript] 이벤트  (0) 2014.12.25
[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23

[JavaScript] 이벤트 등록방법


이벤트 등록방법


1. inline

인라인(inline) 방식으로 이벤트를 등록하는 방법을 알아보자. 인라인 방식은 이벤트를 이벤트 대상의 태그 속성으로 지정하는 것이다.(해당 태그안에 이벤트가 속성으로 직접 들어간 경우)  

다음은 버튼을 클릭했을 때 Hello world를 경고창으로 출력한다.


<input type="button" onclick="alert('Hello world');" value="button" />

이벤트가 발생한 대상을 필요로하는 경우 this를 통해서 참조할 수 있다.

자바스크립트에서 this는 어떤 함수에서 this를 사용한다는 것은  그 함수가 속해있는 객체를 의미(자기 자신을 의미)


<!--자기 자신을 참조하는 불편한 방법-->

<input type="button" id="target" onclick="alert('Hello world, '+document.getElementById('target').value);" value="button" />

<!--this를 통해서 간편하게 참조할 수 있다-->

<input type="button" onclick="alert('Hello world, '+this.value);" value="button" />

this는 이벤트가 동작하고 있는 엘리먼트(input)을 가리킨다. --> 짧고 편리하게 코드를 작성할 수 있다.


인라인 방식은 태그에 이벤트가 포함되기 때문에 이벤트의 소재를 파악하는 것이 편리하다. 하지만 정보인 HTML과 제어인 JavaScript가 혼재된 형태이기 때문에 바람직한 방법이라고 할수는 없다. 


2. 프로퍼티 리스너

프로퍼티 리스너 방식은 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식이다. 인라인 방식에 비해서 HTML과 JavaScript를 분리할 수 있다는 점에서 선호되는 방식이지만 뒤에서 배울 addEventListener 방식을 추천한다. 

<input type="button" id="target" value="button" />

<script>

    var t = document.getElementById('target');

    t.onclick = function(){

        alert('Hello world');

    }

</script>

t라는 객체중에 onclick(내장됨) 프로퍼티에 정의된 메소드를 실행하게된다. 

 

(1) 이벤트 객체

이벤트가 실행된 맥락의 정보가 필요할 때는 이벤트 객체를 사용한다. 이벤트 객체는 이벤트가 실행될 때 이벤트 핸들러의 인자로 전달된다. 

<body>

    <input type="button" id="target" value="button" />

<script>

    var t = document.getElementById('target');

    t.onclick = function(event){

        alert('Hello world, '+event.target.value)

        // console.dir(event); --> 이벤트에 대한 다양한 정보를 출력한다.

    } --> 이벤트 핸들러

// 익명함수의 첫번째 인자로 event객체를 전달하기로 약속되어 있다. 이벤트 호출될때 event 파라미터를 통해서 현재 발생한 이벤트에 대한 다양한 정보를 얻을 수 있다.

// input button을 클릭하면 이에 해당하는 이벤트 핸들러가 호출된다. 호출시 이벤트 객체(event)를 전달한다. 

// 이 코드에서는 event 객체가 가진 프로퍼티 중에서 target 프로퍼티를 사용한다.

// target 프로퍼티는 이벤트가 호출된 시점에서 그 이벤트가 어디서 발생했는지를 알 수 있게 해주는 프로퍼티이다.

// value는 target이 되는 객체의 value 값을 말한다. 여기서는 value="button" 이다.

</script>

실행결과)

Hello world, button


ie8 이하 버전에서는 이벤트 객체를 핸들러의 인자가 아니라 전역객체의 event 프로퍼티로 제공한다. 또한 target 프로퍼티도 지원하지 않는다. 아래는 이 문제를 해소하기 위한 코드다.

<input type="button" id="target" value="button" />

<script>

    var t = document.getElementById('target');

    t.onclick = function(event){

        var event = event || window.event;// window.event는 IE 브라우저의 이벤트 프로퍼티(크로스 브라우징)

        var target = event.target || event.srcElement;

        alert('Hello world, '+target.value)

    }

</script>


3. addEventListener()

addEventListener은 이벤트를 등록하는 가장 권장되는 방식이다. 이 방식을 이용하면 여러개의 이벤트 핸들러를 등록할 수 있다.

<input type="button" id="target" value="button" />

<script>

    var t = document.getElementById('target');

    t.addEventListener('click', function(event){// click 이벤트 발생시, 두번째 인자의 함수가 실행된다.

        alert('Hello world, '+event.target.value);//프로퍼티 리스너 유사(두번째 인자)

    });

</script>

이 방식은 ie8이하에서는 호환되지 않는다. 


ie에서는 attachEvent 메소드를 사용해야 한다. jQuery를 사용하면 호환성 문제 해결된다.

var t = document.getElementById('target');

if(t.addEventListener){//false=undefinded

    t.addEventListener('click', function(event){

        alert('Hello world, '+event.target.value);

    }); 

} else if(t.attachEvent){//addEventListener이 없다면 attachEvent를 사용한다.

    t.attachEvent('onclick', function(event){//attachEvent는 onclick

        alert('Hello world, '+event.target.value);

    })

}


이 방식의 중요한 장점은 하나의 이벤트 대상에 복수의 동일 이벤트 타입 리스너를 등록할 수 있다는 점이다. 

addEventListner는 이벤트를 덮어쓰는 것이 아니라 add해주는 것이라서 복수로 사용이 가능한다.

뒷 단원 캡처링과 버블링이란 개념은 이벤트 전파 방식도 복수의 이벤트가 설치될 경우를 전제로 하므로 addEventListener로 이벤트 등록 방식을 사용할 경우에만 해당한다.

<input type="button" id="target" value="button" />

<script>

    var t = document.getElementById('target');

    t.addEventListener('click', function(event){

        alert(1);

    });

    t.addEventListener('click', function(event){

        alert(2);

    });

</script>

프로퍼티 리스너 방식은 하나만 실행된다.--> 위 예제에서는 '2'(alert)만 실행된다.


이벤트 객체를 이용하면 복수의 엘리먼트에 하나의 리스너를 등록해서 재사용할 수 있다. 

<input type="button" id="target1" value="button1" />

<input type="button" id="target2" value="button2" />

<script>

    var t1 = document.getElementById('target1');

    var t2 = document.getElementById('target2');

    function btn_listener(event){ // btn_listener는 이벤트 리스너로 사용될 함수이다.

        switch(event.target.id){// 각각 event 객체로 전달된 target 프로퍼티에서 id의 값을 알 수 있다.

            case 'target1':

                alert(1);

                break;

            case 'target2':

                alert(2);

                break;

        }

    }

    t1.addEventListener('click', btn_listener); // click시 t1의 식별자로 btn_listener 이벤트가 실행된다.

    t2.addEventListener('click', btn_listener); // click시 t2의 식별자로 btn_listener 이벤트가 실행된다.

    // 이제 버튼 2개를 이용하여 하나의 이벤트 핸들러로 이벤트를 처리할 수 있다.--> 많은 코드를 재활용할 수 있다.

</script>



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트 타입  (0) 2014.12.25
[JavaScript] 이벤트  (0) 2014.12.25
[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23

[JavaScript] 이벤트


이벤트


1. 이벤트란?

이벤트(event)는 어떤 사건을 의미한다. 브라우저에서의 사건이란 사용자가 클릭을 했을 '때', 스크롤을 했을 '때', 필드의 내용을 바꾸었을 '때'와 같은 것을 의미한다. 

<!DOCTYPE html>

<html>

<body>

    <!-- 사용자가 클릭했을 때 자바스크립트 함수 실행 -->

    <input type="button" onclick="alert(window.location)" value="alert(window.href)" />

    <input type="button" onclick="window.open('bom.html')" value="window.open('bom.html')" />

</body>

</html>

onclick 속성의 자바스크립트 코드(alert(window.location))는 사용자가 이 버튼을 클릭 했을 '때' 실행된다. 즉 js 개발자는 어떤 일이 발생했을 때 실행 되어야 하는 코드를 등록하고, 브라우저는 그 일이 발생했을 때 등록된 코드를 실행하게 된다. 이러한 방식을 이벤트 프로그래밍이라고 한다.


(1) event target

target은 이벤트가 일어날 객체(button)를 의미한다. 아래 코드에서 타겟은 버튼 태그에 대한 객체가 된다.

<input type="button" onclick="alert(window.location)" value="alert(window.href)" />


(2) event type

이벤트의 종류를 의미한다. 위의 예제에서는 click이 이벤트 타입이다. 그 외에도 scroll은 사용자가 스크롤을 움직였다는 이벤트이고, mousemove는 마우스가 움직였을 때 발생하는 이벤트이다.

이벤트의 종류는 이미 약속되어 있다. 아래 링크는 브라우저에서 지원하는 이벤트의 종류를 보여준다.

https://developer.mozilla.org/en-US/docs/Web/Reference/Events


(3) event handler

이벤트가 발생했을 때 동작하는 코드를 의미한다. 위의 예제에서는 alert(window.location)이 여기에 해당한다. 일반적으로 함수에 많이 쓰인다.


2. 이벤트 핸들러 종류


cf.)

이벤트 타입: click

이벤트 속성: onclick

이벤트 핸들러: whenClick() / 이벤트 타입에 해당하는 이벤트가 발생했을 때 실행되는 함수.

--> 문서 객체에 이벤트에 연결하는 방법을 이벤트 모델이라고 한다.


 이벤트 핸들러

 이벤트 내용

 onclick

 클릭할 때

 ondblclick

 더블클릭할 때

 onkeydown

 키를 눌렀을 때

 onkeypress

 키를 누르고 있을 때

 onkeyup

 눌러진 키를 원래대로 되돌릴 때

 onmousedown

 마우스 버튼을 눌렀을 때

 onmouseup

 마우스 버튼을 뗄 때

 onmouseover

 마우스 포인터가 통과할 때

 onmouseout

 마우스 포인터가 벗어날 때

 onmouse

 마우스 포인터가 이동할 때

 onload

 페이지 읽어올 때

 onunload

 다른 페이지로 이동할 때

 onfocus

 폼 부품이나 창에 초점이 맞춰질 때

 onblur

 폼 부품이나 창으로부터 초점이 벗어날 때

 onsubmit

 폼이 송신될 때

 onreset

 리셋 버튼을 눌렀을 때

 onchange

 입력란의 문자열이나 메뉴에서 선택한 항목에 변화가 있을 때

 onsize

 창의 크기가 변경될 때

 onmove

 창이 이동될 때

 onabor

 그림 읽기를 중단했을 때

 onerror

 파일이 존재하지 않거나 그림 읽기에 실패했을 때

 onselect

 입력란의 문자열이 선택될 때


3. 이벤트 전파(버블링과 캡처링)

캡처링과 버블링이란 개념은 이벤트 전파 방식도 복수의 이벤트가 설치될 경우를 전제로 하므로 addEventListener로 이벤트 등록 방식을 사용할 경우에만 해당한다.
HTML 태그는 중첩되어 있다. 따라서 특정한 태그에서 발생하는 이벤트는 중첩되어 있는 태그들 모두가 대상이 될 수 있다. 이런 경우 중첩된 태그들에 이벤트가 등록 되어 있다면 어떻게 처리 될까? 


<html>
    <head>
        <style>
            html{border:5px solid red;padding:30px;}
            body{border:5px solid green;padding:30px;}
            fieldset{border:5px solid blue;padding:30px;}
            input{border:5px  solid black;padding:30px;}
        </style>
    </head>
    <body>
        <fieldset>
            <legend>event propagation</legend>
            <input type="button" id="target" value="target">          
        </fieldset>
        <script>
        function handler(event){
            var phases = ['capturing', 'target', 'bubbling']
            console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]); //nodeName:input
        }
        document.getElementById('target').addEventListener('click', handler, true);
        document.querySelector('fieldset').addEventListener('click', handler, true);
        document.querySelector('body').addEventListener('click', handler, true);
        document.querySelector('html').addEventListener('click', handler, true);
        </script>
    </body>
</html>
실행결과)
INPUT HTML capturing
INPUT BODY capturing
INPUT FIELDSET capturing
INPUT INPUT target 

event.target.nodeName:INPUT ==> target은 언제나 <input> 태그를 가리킨다. 여러 계층속에서 가장 구체적인 태그가 target이다.
this.nodeName:FIELDSET ==> 이벤트 핸들러가 호출된 태그이다.
phase[event.eventPhase-1]:capturing ==> 부모태그에서 자식태그로 이벤트가 호출되는 방식

이벤트 핸들러가 설치되는 순서: html -> body -> fieldset -> input
--> click 이전의 단계로 document.querySelector('html').addEventListener('click', handler, false); 와 같은 기술 순서와 무관함을 혼동하지 말자.

이벤트가 부모에서부터 발생해서 자식으로 전파되고 있다. 이러한 방식을 capturing이라고 한다. ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않는다.

코드를 아래와 같이 변경해보자.
document.getElementById('target').addEventListener('click', handler, false); //false면 버블링으로 변환 
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', handler, false);
document.querySelector('html').addEventListener('click', handler, false);
실행결과)
INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling
INPUT HTML bubbling
차이점은 addEventListener의 3번째 인자가 false로 변경 되었다.
이벤트 핸들러가 설치되는 순서가 이전 코드와 반대로 되어 있다.

이번에는 순서가 반대로 되었다. 자식부터 부모로 이벤트가 전파되는 것을 버블링(bubbling)이라고 한다.
이벤트 전파를 중간에 가로막을 수도 있다.
아래처럼 코드를 변경해보자. 
function handler(event){
    var phases = ['capturing', 'target', 'bubbling']
    console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
}
function stophandler(event){
    var phases = ['capturing', 'target', 'bubbling']
    console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
    event.stopPropagation();
}
document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', stophandler, false);
document.querySelector('html').addEventListener('click', handler, false);
실행결과)
INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling
INPUT HTML bubbling
참고로 ie9 이전의 브라우저에서는 이벤트 전파을 막기 위해서 event.cancelBubble 프로퍼티를 사용해야 한다.

이벤트 전파가 html로 가지 않고 body에서 멈추었다.

4. 기본동작의 취소
웹브라우저의 구성요소들은 각각 기본적인 동작 방법을 가지고 있다.
- 텍스트 필드에 포커스를 준 상태에서 키보드를 입력하면 텍스트가 입력된다.
- 폼에서 submit 버튼을 누르면 데이터가 전송된다.
- a 태그를 클릭하면 href 속성의 URL로 이동한다.
- 이러한 기본적인 동작들을 기본 이벤트라고 하는데 사용자가 만든 이벤트를 이용해서 이러한 기본 동작을 취소할 수 있다.

(1) inline
이벤트의 리턴값이 false이면 기본 동작이 취소된다.
<p>
    <label>prevent event on</label><input id="prevent" type="checkbox" name="eventprevent" value="on" />
</p>
<p>
    <a href="http://opentutorials.org" onclick="if(document.getElementById('prevent').checked) return false;">opentutorials</a>
</p><!--if 조건문이 true라면 return false -->
<p>
    <form action="http://opentutorials.org" onsubmit="if(document.getElementById('prevent').checked) return false;">
            <input type="submit" /><!-- onsubmit: submit(submit 클릭시) 했을때 발생하는 이벤트이다. -->
    </form>
</p>

(2) property 방식
리턴 값이 false이면 기본동작이 취소된다. 
<p>
    <label>prevent event on</label><input id="prevent" type="checkbox" name="eventprevent" value="on" />
</p>
<p>
    <a href="http://opentutorials.org">opentutorials</a>
</p>
<p>
    <form action="http://opentutorials.org">
            <input type="submit" />
    </form>
</p>
<script>
    document.querySelector('a').onclick = function(event){
        if(document.getElementById('prevent').checked)<!-- true 라면 return false-->
            return false;
    };
     
    document.querySelector('form').onclick = function(event){
        if(document.getElementById('prevent').checked)
            return false;
    };
</script>

(3) addEventListener 방식
이 방식에서는 이벤트 객체의 preventDefault 메소드를 실행하면 기본 동작이 취소된다. 
<p>
      <label>prevent event on</label><input id="prevent" type="checkbox" name="eventprevent" value="on" />
</p>
<p>
      <a href="http://opentutorials.org">opentutorials</a>
</p>
<p>
       <form action="http://opentutorials.org">
             <input type="submit" />
       </form>
</p>
<script>
       document.querySelector('a').addEventListener('click', function(event){
              if(document.getElementById('prevent').checked)
              event.preventDefault();
        });
             
        document.querySelector('form').addEventListener('submit', function(event){
             if(document.getElementById('prevent').checked)
             event.preventDefault();
        }); 
</script>
ie9 이하 버전에서는 event.returnValue를 false로 해야 한다. 


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트 타입  (0) 2014.12.25
[JavaScript] 이벤트 등록방법  (0) 2014.12.25
[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23

[JavaScript] Text 객체


Text 객체



1. 소개

텍스트 객체는 텍스트 노드에 대한 DOM 객체로 CharcterData를 상속 받는다. 


아래는 텍스트 노드를 찾는 예제다. 주목할 것은 DOM에서는 공백이나 줄바꿈도 텍스트 노드라는 점이다.

<p id="target1">노드없음<span>Hello world</span></p>

<p id="target2">줄바꿈 노드가 숨겨있음

    <span>Hello world</span>

</p>

<script>

var t1 = document.getElementById('target1').firstChild;

var t2 = document.getElementById('target2').firstChild;

 

console.log(t1.firstChild.nodeValue);

try{

    console.log(t2.firstChild.nodeValue);   

} catch(e){

    console.log(e);

}

console.log(t2.nextSibling.firstChild.nodeValue);

</script>

   

-->DOM에서는 공백조차도 분명히 존재하는 객체에 매핑되어 있다.

실행결과)

Hello world

TypeError {stack: (...), message: "Cannot read property 'nodeValue' of null"}

Hello world


2. 주요 기능


(1)  값

텍스트 노드의 값을 가져오는 API

- data

- nodeValue


(2) 조작

- appendData()

- deleteData()

- insertData()

- replaceData()

- subStringData()


(3) 생성

- docuemnt.createTextNode()


3. 값 API

텍스트 노드는 DOM에서 실질적인 데이터가 저장되는 객체이다. 따라서 텍스트 노드에는 값과 관련된 여러 기능들이 있는데 이번 시간에는 값을 가져오는 두개의 API를 알아본다

- nodeValue

- data

<ul>

    <li id="target">html</li> 

    <li>css</li>

    <li>JavaScript</li>

</ul>

<script>

    var t = document.getElementById('target').firstChild;

    console.log(t.nodeValue);

    console.log(t.data);

</script>


t.nodeValue="!!": 텍스트의 문자 값이 '!!'로 바뀐다.


4. 조작 API

텍스트 노드가 상속 받은 CharacterData 객체는 문자를 제어할 수 있는 다양한 API를 제공한다. 아래는 조작과 관련된 API들의 목록이다.

- appendData()

- deleteData()

- insertData()

- replaceData()

- substringData()


<!DOCTYPE html>

<html>

<head>

    <style>

    #target{

        font-size:77px;

        font-family: georgia;

        border-bottom:1px solid black;

        padding-bottom:10px;

    }

    p{

        margin:5px;

    }

    </style>

</head>

<body>

<p id="target">Cording everybody!</p>

<p> data : <input type="text" id="datasource" value="JavaScript" /></p>

<p>   start :<input type="text" id="start" value="5" /></p>

<p> end : <input type="text" id="end" value="5" /></p>

<p><input type="button" value="appendData(data)" onclick="callAppendData()" />

<input type="button" value="deleteData(start,end)" onclick="callDeleteData()" />

<input type="button" value="insertData(start,data)" onclick="callInsertData()" />

<input type="button" value="replaceData(start,end,data)" onclick="callReplaceData()" />

<input type="button" value="substringData(start,end)" onclick="callSubstringData()" /></p>

<script>

    var target = document.getElementById('target').firstChild;

    var data = document.getElementById('datasource');

    var start = document.getElementById('start');

    var end = document.getElementById('end');

    function callAppendData(){

        target.appendData(data.value);

    }

    function callDeleteData(){

        target.deleteData(start.value, end.value);

    }

    function callInsertData(){

        target.insertData(start.value, data.value); 

    }

    function callReplaceData(){

        target.replaceData(start.value, end.value, data.value);

    }

    function callSubstringData(){

        alert(target.substringData(start.value, end.value));

    }

</script>

</body>

</html>

'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트 등록방법  (0) 2014.12.25
[JavaScript] 이벤트  (0) 2014.12.25
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23
[JavaScript] Element 객체  (0) 2014.12.22

[JavaScript] Document 객체


Document 객체


1. 소개

Document 객체는 DOM의 스팩이고 이것이 웹브라우저에서는 HTMLDocument 객체로 사용된다. HTMLDocument 객체는 문서 전체를 대표하는 객체라고 할 수 있다. 아래 코드는 이를 보여준다.

<script>

//document 객체는 window 객체의 소속이다.

console.log(window.document);

//document 객체의 자식으로는 Doctype과 html이 있다. 

console.log(window.document.childNodes[0]);

console.log(window.document.childNodes[1]);

</script>


2. 노드 생성 API

document  객체의 주요 임무는 새로운 노드를 생성해주는 역할이다. 이에 대한 내용은 노드 변경 API에서 학습했기 때문에 여기서는 언급하지 않는다.

- createElement()

- createTextNode()


3. 문서 정보 API

- title

- URL

- referrer

- lastModified



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트  (0) 2014.12.25
[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23
[JavaScript] Element 객체  (0) 2014.12.22
[JavaScript] HTMLCollection 객체  (0) 2014.12.22

[JavaScript] Node 객체


Node 객체


1. 소개

Node 객체는 DOM에서 시조와 같은 역할을 한다. 다시 말해서 모든 DOM 객체는 Node 객체를 상속 받는다. Node 객체의 위상을 그림으로 나타내면 아래와 같다. 

모든 엘리먼트, 텍스트, 주석등 HTML코드의 모든 문서의 구성요소들의 객체는 공통적으로 Node라는 객체를 상속받는다.

Node객체는 firstChild, lastChild, nextSibling등의 프로퍼티를 가지고 있어서 이를 이용해서 각각의 Node들을 기준으로해서 자식이 누구인지, 형제가 누구인지 알 수 있다.



2. 주요기능

Node 객체의 주요한 임무는 아래와 같다.


(1) 관계

엘리먼트는 서로 부모, 자식, 혹은 형제자매 관계로 연결되어 있다. 각각의 Node가 다른 Node와 연결된 정보를 보여주는 API를 통해서 문서를 프로그래밍적으로 탐색할 수 있다.

- Node.childNodes//유사배열

- Node.firstChild

- Node.lastChild

- Node.nextSibling

- Node.previousSibling

- Node.contains()

- Node.hasChildNodes()


(2) 노드의 종류

Node 객체는 모든 구성요소를 대표하는 객체이기 때문에 각각의 구성요소가 어떤 카테고리에 속하는 것인지를 알려주는 식별자를 제공한다. 

- Node.nodeType

- Node.nodeName


(3) 값

Node 객체의 값을 제공하는 API

- Node.nodeValue

- Node.textContent


(4) 자식관리

Node 객체의 자식을 추가하는 방법에 대한 API

- Node.appendChild()

- Node.removeChild()


3. Node 관계 API

Node 객체는 Node 간의 관계 정보를 담고 있는 일련의 API를 가지고 있다. 다음은 관계와 관련된 프로퍼티들이다.

- Node.childNodes: 자식노드들을 유사배열에 담아서 리턴한다.

- Node.firstChild: 첫번째 자식노드

- Node.lastChild: 마지막 자식노드

- Node.nextSibling: 다음 형제 노드

- Node.previousSibling: 이전 형제 노드


아래는 위의 API를 이용해서 문서를 탐색하는 모습을 보여준다.

<body id="start">

<ul>

    <li><a href="./532">html</a></li> 

    <li><a href="./533">css</a></li>

    <li><a href="./534">JavaScript</a>

        <ul>

            <li><a href="./535">JavaScript Core</a></li>

            <li><a href="./536">DOM</a></li>

            <li><a href="./537">BOM</a></li>

        </ul>

    </li>

</ul>

<script>

var s = document.getElementById('start');

console.log(1, s.firstChild); // #text(<body>태그와 <ul>태그 사이의 공백(Node타입은 text)

var ul = s.firstChild.nextSibling

console.log(2, ul); // ul

console.log(3, ul.nextSibling); // #text

console.log(4, ul.nextSibling.nextSibling); // script

console.log(5, ul.childNodes); //text, li, text, li, text, li, text

console.log(6, ul.childNodes[1]); // li(html)

console.log(7, ul.parentNode); // body

</script>

</body>




4. 노드 종류 API

노드 작업을 하게 되면 현재 선택된 노드가 어떤 타입인지를 판단해야 하는 경우가 있다. 이런 경우에 사용할 수 있는 API가 nodeType, nodeName이다. 

- Node.nodeType: node의 타입을 의미한다. 

- Node.nodeName: node의 이름 (태그명을 의미한다.)


(1) Node Type

노드의 종류에 따라서 정해진 상수가 존재한다. 아래는 모든 노드의 종류와 종류에 따른 값을 출력하는 예제다.

for(var name in Node){

   console.log(name, Node[name]);

}

실행결과)

ELEMENT_NODE 1 (엘리먼트 노드의 값은 1-->상수)

ATTRIBUTE_NODE 2 

TEXT_NODE 3 

CDATA_SECTION_NODE 4 

ENTITY_REFERENCE_NODE 5 

ENTITY_NODE 6 

PROCESSING_INSTRUCTION_NODE 7 

COMMENT_NODE 8 

DOCUMENT_NODE 9 

DOCUMENT_TYPE_NODE 10 

DOCUMENT_FRAGMENT_NODE 11 

NOTATION_NODE 12 

DOCUMENT_POSITION_DISCONNECTED 1 

DOCUMENT_POSITION_PRECEDING 2 

DOCUMENT_POSITION_FOLLOWING 4 

DOCUMENT_POSITION_CONTAINS 8 

DOCUMENT_POSITION_CONTAINED_BY 16 

DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC 32





숫자는 외우기 힘들다.. 그래서 대안은....


아래 예제는 노드 종류 API를 이용해서 노드를 처리하는 예제다. 어떤함수가 실행될 때 그 함수가 자기 자신을 호출하는 것을 재귀함수라고 하는데 본 예제는 재귀 함수의 예를 보여준다.

<!DOCTYPE html>

<html>

<body id="start">

<ul>

    <li><a href="./532">html</a></li> 

    <li><a href="./533">css</a></li>

    <li><a href="./534">JavaScript</a>

        <ul>

            <li><a href="./535">JavaScript Core</a></li>

            <li><a href="./536">DOM</a></li>

            <li><a href="./537">BOM</a></li>

        </ul>

    </li>

</ul>

<script>

function traverse(target, callback){

// 첫번째 인자: 우리가 조회하려고 하는 루트 엘리먼트 지정 

//두번째 인자: 각각의 엘리먼트를 조회할 때 마다 그 순번에 해당하는 엘리먼트를 사용자가 작성한 함수의 인자로 전달(함수가 전달된다.--> 콜백)

    if(target.nodeType === 1){

    //nodeType이 1(Element)인 경우만 로직 수행--> 텍스트 노드를 배제하기 위함

    //if(target.nodeName === 'A')//a태그만 출력하기 위함

        callback(target);

  // callback 함수가 실행 위함(매개변수는 document.getElementById('start'))

        var c = target.childNodes;

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

            traverse(c[i], callback); 

// 더이상 자식노드가 나오지 않을 때 까지 출력      

        }   

    }

}


traverse(document.getElementById('start'), function(elem){

    console.log(elem);

});

</script>

</body>

</html>


5. 노드 변경 API


(1) 노드 추가

노드의 추가와 관련된 API들은 아래와 같다.

- appendChild(child): 노드의 마지막 자식으로 주어진 엘리먼트 추가

- insertBefore(newElement, referenceElement): appendChild와 동작방법은 같으나 두번째 인자로 엘리먼트를 전달 했을 때 이것 앞에 엘리먼트가 추가된다.


노드를 추가하기 위해서는 추가할 엘리먼트를 생성해야 하는데 이것은 document 객체의 기능이다. 아래 API는 노드를 생성하는 API이다.

- document.createElement(tagname): 엘리먼트 노드를 추가한다.

- document.createTextNode(data): 텍스트 노드를 추가한다. 


<ul id="target">

    <li>HTML</li>

    <li>CSS</li>

</ul>

<input type="button" onclick="callAppendChild();" value="appendChild()" />

<input type="button" onclick="callInsertBefore();" value="insertBefore()" />

<script>

    function callAppendChild(){

        var target = document.getElementById('target');

        var li = document.createElement('li');//<li></li> 태그를 만든다.(text가 비어있음)

        var text = document.createTextNode('JavaScript');//text노드를 만든다.

        li.appendChild(text); // 위의 두개 코드를 결합한다.--> <li>JavaScript</li>

        target.appendChild(li); // <ul>태그 자식인 <li>태그의 맨 끝에 추가된다.

    }

 

    function callInsertBefore(){

        var target = document.getElementById('target');

        var li = document.createElement('li');

        var text = document.createTextNode('jQuery');

        li.appendChild(text);

        target.insertBefore(li, target.firstChild);//<ul>태그 자식인 <li>태그의 맨 앞에 추가된다.

    }

</script>

<li> 앞쪽에 추가된다.--> <ul>,<li>태그 사이의 text 노드 영역에 추가된다.


(2) 노드 제거

노드 제거를 위해서는 아래 API를 사용한다. 이 때 메소드는 삭제 대상의 부모 노드 객체의 것을 실행해야 한다는 점에 유의하자.


- removeChild(child)

<ul>

    <li>HTML</li>

    <li>CSS</li>

    <li id="target">JavaScript</li>

</ul>

<input type="button" onclick="callRemoveChild();" value="removeChild()" />

<script>

    function callRemoveChild(){

        var target = document.getElementById('target');

        target.parentNode.removeChild(target);// target의 부모Node로 갔다가 다시 그 부모의 자식인 target을 삭제--> DOM이  비판받는 이유

    }

</script>


(3) 노드 바꾸기

노드 바꾸기에는 아래 API가 사용된다.


- replaceChild(newChild, oldChild)

<ul>

    <li>HTML</li>

    <li>CSS</li>

    <li id="target">JavaScript</li>

</ul>

<input type="button" onclick="callReplaceChild();" value="replaceChild()" />

<script>

    function callReplaceChild(){

        var a = document.createElement('a');

        a.setAttribute('href', 'http://opentutorials.org/module/904/6701');

        a.appendChild(document.createTextNode('Web browser JavaScript'));

 

        var target = document.getElementById('target');

        target.replaceChild(a,target.firstChild);//a: 교체대상 태그, target.firstChild: 교체하려고 하는 내용

    }

</script>


6. 문자열로 노드 제어

노드 변경 API에서는 여러 메소드를 이용해서 노드를 제어하는 방법에 대해서 알아봤다. 그런데 이 방식은 복잡하고 장황하다. 좀 더 편리하게 노드를 조작하는 방법을 알아보자.


(1) innerHTML

innerHTML는 문자열로 자식 노드를 만들 수 있는 기능을 제공한다. 또한 자식 노드의 값을 읽어올 수도 있다. 

<ul id="target">

    <li>HTML</li>

    <li>CSS</li>

</ul>

<input type="button" onclick="get();" value="get" />

<input type="button" onclick="set();" value="set" />

<script>

    function get(){

        var target = document.getElementById('target');

        alert(target.innerHTML); // id가 target의 하위 HTML 태그의 text노드 값 까지 그대로 화면에 출력된다.

    }

    function set(){

        var target = document.getElementById('target');

        target.innerHTML = "<li>JavaScript Core</li><li>BOM</li><li>DOM</li>";// 기존의 노드가 새롭게 변경한 코드로 변경된다.--> id가 target의 하위태그를 문자열로 지정할 수 있다.

    }

</script>

                                                         

(2) outerHTML

outerHTML은 선택한 엘리먼트를 포함해서 처리된다.

<ul id="target">

    <li>HTML</li>

    <li>CSS</li>

</ul>

<input type="button" onclick="get();" value="get" />

<input type="button" onclick="set();" value="set" />

<script>

    function get(){

        var target = document.getElementById('target');

        alert(target.outerHTML);

    }

    function set(){

        var target = document.getElementById('target');

        target.outerHTML = "<ol><li>JavaScript Core</li><li>BOM</li><li>DOM</li></ol>";

    }

</script>

innerHTML: 자신을 제외한 하위 엘리먼트가 대상 

outerHTML: 자신을 포함한 하위 엘리먼트까지 대상


(3) innerText, outerText

innerHtml, outerHTML과 다르게 이 API들은 값을 읽을 때는 HTML 코드를 제외한 문자열을 리턴하고, 값을 변경할 때는 HTML의 코드를 그대로 추가한다.

<ul id="target">

    <li>HTML</li>

    <li>CSS</li>

</ul>

<input type="button" onclick="get();" value="get" />

<input type="button" onclick="set();" value="set" />

<script>

    function get(){

        var target = document.getElementById('target');

        alert(target.innerText);

    }

    function set(){

        var target = document.getElementById('target');

        target.innerText = "<li>JavaScript Core</li><li>BOM</li><li>DOM</li>";//태그 내용값(text)만 출력되는 것이 아니라 그 태그까지 출력된다.

    }

</script>


(4) insertAdjacentHTML()

좀 더 정교하게 문자열을 이용해서 노드를 변경하고 싶을 때 사용한다.

<ul id="target">

    <li>CSS</li>

</ul>

<input type="button" onclick="beforebegin();" value="beforebegin" />

<input type="button" onclick="afterbegin();" value="afterbegin" />

<input type="button" onclick="beforeend();" value="beforeend" />

<input type="button" onclick="afterend();" value="afterend" />

<script>

    function beforebegin(){

        var target = document.getElementById('target');

        target.insertAdjacentHTML('beforebegin','<h1>Client Side</h1>');

    }

    function afterbegin(){

        var target = document.getElementById('target');

        target.insertAdjacentHTML('afterbegin','<li>HTML</li>');

    }

    function beforeend(){

        var target = document.getElementById('target');

        target.insertAdjacentHTML('beforeend','<li>JavaScript</li>');

    }

    function afterend(){

        var target = document.getElementById('target');

        target.insertAdjacentHTML('afterend','<h1>Server Side</h1>');

    }

</script>



                               

'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Element 객체  (0) 2014.12.22
[JavaScript] HTMLCollection 객체  (0) 2014.12.22
[JavaScript] HTMLElement 객체  (0) 2014.12.22

[JavaScript] Element 객체


Element 객체


1. 소개

Element 객체는 엘리먼트를 추상화한 객체다. HTMLElement 객체와의 관계를 이해하기 위해서는 DOM의 취지에 대한 이해가 선행되야 한다. 

DOM은 HTML만을 제어하기 위한 모델이 아니다. HTML이나 XML, SVG, XUL과 같이 마크업 형태의 언어를 제어하기 위한 규격이기 때문에 Element는 마크업 언어의 일반적인 규격에 대한 속성을 정의하고 있고, 각각의 구체적인 언어(HTML,XML,SVG)를 위한 기능은 HTMLElement, SVGElement, XULElement와 같은 객체를 통해서 추가해서 사용하고 있다.


2. 다른 객체들과의 관계

DOM의 계층구조에서 Element 객체의 위치는 아래와 같다.



※ Element와 HTMLElement를 구분하는 이유

DOM이라는 것이 HTML만 제어하는 것이 아니다.--> 마크업 언어(XML, HTML, SVG 등등)< > 를 제어하기 위해 표준이 DOM이다.(마크업 언어는 Element가 있다.)

(엘리먼트가 HTML에만 있는 것이 아니다.)


3. 주요기능

(1)  식별자

문서내에서 특정한 엘리먼트를 식별하기 위한 용도로 사용되는 API

- Element.classList

- Element.className

- Element.id

- Element.tagName


(2) 조회

엘리먼트의 하위 엘리먼트를 조회하는 API

- Element.getElementsByClassName

- Element.getElementsByTagName

- Element.querySelector

- Element.querySelectorAll


(3) 속성

엘리먼트의 속성을 알아내고 변경하는 API

- Element.getAttribute(name)

- Element.setAttribute(name, value)

- Element.hasAttribute(name);

- Element.removeAttribute(name);


4. 식별자 API

엘리먼트를 제어하기 위해서는 그 엘리먼트를 조회하기 위한 식별자가 필요하다. 

HTML에서 엘리먼트의 이름과 id 그리고 class는 식별자로 사용된다. 식별자 API는 이 식별자를 가져오고 변경하는 역할을 한다.


(1) Element.tagName

해당 엘리먼트의 태그 이름을 알아낸다. 태그 이름을 변경하지는 못한다.

<ul>

    <li>html</li>

    <li>css</li>

    <li id="active" class="important current">JavaScript</li>

</ul>

<script>

console.log(document.getElementById('active').tagName)//읽기전용

</script>


(2) Element.id

문서에서 id는 단 하나만 등장할 수 있는 식별자다. 아래 예제는 id의 값을 읽고 변경하는 방법을 보여준다. 

<ul>

    <li>html</li>

    <li>css</li>

    <li id="active">JavaScript</li>

</ul>

<script>

var active = document.getElementById('active');

console.log(active.id);

active.id = 'deactive';// id 값을 deactive로 변경

console.log(active.id);

</script>


(3) Element.className

클래스는 여러개의 엘리먼트를 그룹핑할 때 사용한다.

<ul>

    <li>html</li>

    <li>css</li>

    <li id="active">JavaScript</li>

</ul>

<script>

var active = document.getElementById('active');

// class 값을 변경할 때는 프로퍼티의 이름으로 className을 사용한다.

active.className = "important current";

console.log(active.className);

// 클래스를 추가할 때는 아래와 같이 문자열의 더한다.

active.className += " readed"


(4) Element.classList

className에 비해서 훨씬 편리한 사용성을 제공한다.

<ul>

    <li>html</li>

    <li>css</li>

    <li id="active" class="important current">JavaScript</li>

</ul>

<script>

function loop(){

    //var active = document.getElementById('active');

    for(var i=0; i<active.classList.length; i++){

        console.log(i, active.classList[i]);

    }

}

// 클래스를 추가

</script>

<input type="button" value="DOMTokenList" onclick="console.log(active.classList);" />

<input type="button" value="조회" onclick="loop();" />

<input type="button" value="추가" onclick="active.classList.add('marked');" />

<input type="button" value="제거" onclick="active.classList.remove('important');" />

<input type="button" value="토글" onclick="active.classList.toggle('current');" />


DOMTokenList: class= a,b,c라면 각각의 a,b,c를 담아놓은 객체가 바로 DOMTokenList이다. -->유사배열



5. 조회 API

조회 API는 엘리먼트를 조회하는 기능이다. 조회 방법에 대해서는 이미 여러차례 살펴봤기 때문에 이번 시간에 알아볼 내용은 조회 대상을 제한하는 방법에 대한 것이다. 

지금까지 document.getElementsBy* 메소드를 통해서 엘리먼트를 조회했다. document 객체는 문서 전체를 의미하는 엘리먼트이기 때문에 document의 조회 메소드는 문서 전체를 대상으로 엘리먼트를 조회한다. Element 객체 역시도 getElementsBy* 엘리먼트를 가지고 있는데 Element 객체의 조회 메소드는 해당 엘리먼트의 하위 엘리먼트를 대상으로 조회를 수행한다. 

<ul>

    <li class="marked">html</li>

    <li>css</li>

    <li id="active">JavaScript

        <ul>

            <li>JavaScript Core</li>

            <li class="marked">DOM</li>

            <li class="marked">BOM</li>

        </ul>

    </li>

</ul>

<script>

    var list = document.getElementsByClassName('marked');

    console.group('document');

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

        console.log(list[i].textContent);

    }

    console.groupEnd();

     

    console.group('active');

    var active = document.getElementById('active');     

    var list = active.getElementsByClassName('marked');

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

        console.log(list[i].textContent);

    }

    console.groupEnd();

</script>

실행결과)


6. 속성 API

속성은 HTML에서 태그명만으로는 부족한 부가적인 정보라고 할 수 있다. 이 속성을 어떻게 제어하는가 알아보자. 


속성을 제어하는 API는 아래와 같다. 각각의 기능은 이름을 통해서 충분히 유추할 수 있을 것이다.

- Element.getAttribute(name)

- Element.setAttribute(name, value)

- Element.hasAttribute(name);

- Element.removeAttribute(name);


<a id="target" href="http://opentutorials.org">opentutorials</a>

<script>

var t = document.getElementById('target');

console.log(t.getAttribute('href')); //http://opentutorials.org

t.setAttribute('title', 'opentutorials.org'); // title 속성의 값을 설정한다.

console.log(t.hasAttribute('title')); // true, title 속성의 존재여부를 확인한다.

t.removeAttribute('title'); // title 속성을 제거한다.

console.log(t.hasAttribute('title')); // false, title 속성의 존재여부를 확인한다.--> true, false 리턴

</script>


(2) 속성과 프로퍼티

모든 엘리먼트의 (HTML)속성은 (JavaScript 객체의) 속성과 프로퍼티로 제어가 가능하다. 예제를 보자.

<p id="target">

    Hello world

</p>

<script>

    var target = document.getElementById('target');


    // attribute 방식

    target.setAttribute('class', 'important');

    // property 방식

    target.className = 'important';

</script>

setAttribute('class', 'important')와 className = 'important'는 같은 결과를 만든다. 하지만 전자는 attribute 방식(속성이라고 부르겠다)이고 후자는 property 방식이다.

property 방식은 좀 더 간편하고 속도도 빠르지만 실제 html 속성의 이름과 다른 이름을 갖는 경우가 있다. 그것은 자바스크립트의 이름 규칙 때문이다.

심지어 속성과 프로퍼티는 값이 다를수도 있다. 아래 코드를 실행한 결과는 속성과 프로퍼티의 값이 꼭 같은 것은 아니라는 것을 보여준다.

<a id="target" href="./demo1.html">ot</a>

<script>

//현재 웹페이지가 http://localhost/webjs/Element/attribute_api/demo3.html 일 때 

var target = document.getElementById('target');

// http://localhost/webjs/Element/attribute_api/demo1.html 

console.log('target.href', target.href);

// ./demo1.html 

console.log('target.getAttribute("href")', target.getAttribute("href"));

</script>


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23
[JavaScript] HTMLCollection 객체  (0) 2014.12.22
[JavaScript] HTMLElement 객체  (0) 2014.12.22
[JavsScript] 제어 대상을 찾기  (0) 2014.12.21

[JavaScript] HTMLCollection 객체


HTMLCollection 객체


HTMLCollection은 리턴 결과가 복수인 경우에 사용하게 되는 객체다. 유사배열로 배열과 비슷한 사용방법을 가지고 있지만 배열은 아니다. 

HTMLCollection의 목록은 실시간으로 변경된다. 아래 코드를 보자.

<!DOCTYPE html>

<html>

<body>

<ul>

    <li>HTML</li>

    <li>CSS</li>

    <li id="active">JavaScript</li>

</ul>

<script>

console.group('before');

var lis = document.getElementsByTagName('li');

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

    console.log(lis[i]);

}

console.groupEnd();

console.group('after');

lis[1].parentNode.removeChild(lis[1]);

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

    console.log(lis[i]);

}

console.groupEnd();

</script>

</body>

</html>

실행결과)


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] Node 객체  (1) 2014.12.23
[JavaScript] Element 객체  (0) 2014.12.22
[JavaScript] HTMLElement 객체  (0) 2014.12.22
[JavsScript] 제어 대상을 찾기  (0) 2014.12.21
[JavaScript] 전역객체 window  (0) 2014.12.21