HTML5 jQuery 강좌 #2 (20120328)

2012. 3. 27. 10:4299. 정리전 - IT/12. Javascript


Cookie -> WEB Storage (client side data 저장 (key-value)) 쿠키의 대체는 아닌 새로운 기술


HTTP의 특징(stateless)

 - 클라이언트의 커넥션을 서버에 한번 요청을 하면 응답을 주고 끊어버린다

 - 클라이언트는 서버에 접속시 마다 서버는 새로운 커넥션으로 인식하므로 동일 클라이언트에서 접속하더라도 구분할 수 없다.

   - 대안 : session(서버side에 클라이언트정보 저장)

               cookie(클라이언트의 상태정보 저장)의 활용

                - request 에 cookie 데이터를 브라우저가 알아서 해당 도메인을 response할때 head에 붙여 서버로 넘겨주는 형태

                  (서버가 필요없는 쿠키정보를 모두 넘겨주는 형태임)


----------------------------------------------------------------

 WEB Storage 구현

----------------------------------------------------------------

01. 실장

<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<script>

window.onload = function(){

var removeBtn = document.getElementById("removeBtn");

var addBtn    = document.getElementById("addBtn");

removeBtn.addEventListener("click", remove); //removeBtn에 click이벤트 발생시 remove함수 호출

addBtn.addEventListener("click", add);       //addBtn에 click이벤트 발생시 add함수 호출

load();

}

// SelectBox 갱신

function load() {

var list = document.getElementById("list");

list.innerHTML = "";

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

var key = localStorage.key(i);

list.options[list.options.length] = new Option(localStorage[key], key);

}

}

function remove() {

var list = document.getElementById("list");

if (list.selectedIndex < 0) return; // 아무것도 선택되지 않았다면

var selected = list.options[list.selectedIndex].value;

localStorage.removeItem(selected);

load();

}

function add() {

var key   = document.getElementById("key").value;

var value = document.getElementById("value").value;

localStorage[key] = value;

load();

}

</script>

</head>

<body>

<h1>Web Storage Test</h1>

<p>

<select id="list" style="width:100px"></select>

<button id="removeBtn">remove</button>

</p>

<p>

key : <input type="text" id="key"> - value <input type="text" id="value">

<button id="addBtn">add</button>

</p>

</body>

</html>


02. 실행




 (F12를 누르면 나옴)




----------------------------------------------------------------

 WEB SQL Database 구현 (W3C 에서 Drop 한 메소드임)

----------------------------------------------------------------

Drop된 이유

  00. W3C는 브라우져 밴더들에게 강제로 SQLite를 사용하게 할 수 있는 권한이 없음

  01. SQL을 모르는 사람들위해

  02. 특정 브라우져 밴드가 독자DB를 임베디드 시켰을때 SQL문이 틀려질 수 있음



 SQLite(RDBMS) - OpenSource, 안정성, 경량, 이용편의성

  - 브라우저에 내장되어 있으므로 DB Connection필요없음, 단위처리, 트렌잭션처리 가능


01. 실장


<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<script>

// DB 초기화

var db = openDatabase("dbtest", "", "DB TEST", "1024*1024");

// Table 준비

db.transaction(function(tx) {

tx.executeSql("create table if not exists m_tb ("

                   + "_id integer primary key autoincrement,"

                   + "name not null,"

                   + "phone not null)");

});

window.onload = function(){

var removeBtn = document.getElementById("removeBtn");

var addBtn    = document.getElementById("addBtn");

removeBtn.addEventListener("click", remove); //removeBtn에 click이벤트 발생시 remove함수 호출

addBtn.addEventListener("click", add);       //addBtn에 click이벤트 발생시 add함수 호출

load();

}

// SelectBox 갱신

function load() {

db.transaction(function(tx) {

tx.executeSql("select * from m_tb", [],                    // ?에 넣을값

            function(tx, rs) {                           // 성공시

var list = document.getElementById("list");

list.innerHTML = "";

var rows = rs.rows;

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

var row = rows.item(i);

list.options[list.options.length] = new Option(row.name, row._id);

}

});

});

var list = document.getElementById("list");

list.innerHTML = "";

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

var key = localStorage.key(i);

list.options[list.options.length] = new Option(localStorage[key], key);

}

}

    function remove() {

        var list = document.getElementById("list");

        if (list.selectedIndex < 0) return; // 아무것도 선택되지 않았다면

        var selected = list.options[list.selectedIndex].value;

        db.transaction(function(tx) {

            tx.executeSql("delete from m_tb where _id=?", [selected], // ?에 넣을값

            function() {                                // 성공시

load();

}); 

        });

    }

    function add() {

        var name  = document.getElementById("name").value;

        var phone = document.getElementById("phone").value;

        db.transaction(function(tx) {

            tx.executeSql("insert into m_tb (name,phone) values(?,?)", [name, phone],

                         function() {                                // 성공시

                            load();

                         });

        });

    }

</script>

</head>

<body>

<h1>Web SQL Database Test</h1>

<p>

<select id="list" style="width:100px"></select>

<button id="removeBtn">remove</button>

</p>

<p>

name : <input type="text" id="name"> - phone <input type="text" id="phone">

<button id="addBtn">add</button>

</p>

</body>

</html>


02. 결과 (F12를 누르면 나옴)





--------------------------------
--------------------------------

 Indexed DB (SQLite의 대안) - 지원되는 브라우져가 현시점 극소

----------------------------------------------------------------

객체를 구조화시켜 내부적으로는 밴더가 어떠한 방식으로든(예:SQLite이용) 브라우져에 저장 가능하도록 하는 방식



-------------------------------------------------------------------------------------------------



----------------------------------------------------------------

Communucation API

----------------------------------------------------------------


동기통신 - 클라이언트에서 서버로 데이터 요청시 브라우저에서 만들어진 request 데이터를 서버에서 받아, 서버는 response          

                데이터를 만들어 클라이언트에게 전달해 준다 (클라이언트는 서버의 응답을 받을 때 까지, 어떠한 동작도 할 수 없다)

                비동기통신 - AJAX


stateless - client 접속상태유지를 위해 session, cookie, web storage

                realtime data통신 불가 : C/S 커넥션이 끊어진 상태로, 서버로부터는 클라이언트에게 데이터를 전송할 수 없다.

                대안 : polling (클라이언트에서 일정시간 서버에 연결시도) - 네트웍 트레픽 초래

                         comet : 클라이언트에서 요청을 하면 서버는 응답을 하지 않고 있다가 이벤트가 발생되면 서버에서 그때서야

                                    응답을 함 - 클라이언트는 대기화면이지만 innerFrame=0 부분으로 넘기고 부모창으로 넘김

                 HTML5 대안 : web socket (web socket 전용 서버가 필요함), server sent event (주기적인 C/S 통신)


SameOrigin Policy - 서로 다른 서버에서 하나의 클라이언트와 접속되었을때 클라이언트의 정보를 공유할 수 없다

                                 (서브 도메인의 경우도 메인도메인과 다른 도메인으로 취급)

                대안 : Cross Document Message


Web Worker - JavaScript Thread Program (node.js, 서버:구글의 V8엔진) - 모바일에서 안됨



----------------------------------------------------------------

 Crocess Document

----------------------------------------------------------------

상이한 도메인 (서로다른 도메인을 가진 document 간의 객체 전송을 위한 기술)


01. 환경설정



02. Dynamic Web Project 로 프로젝트 생성



03. 프로젝트 생성 계속



04. 아래와 같이 코드 실장 (일단 inner.html 로 twitter 의 검색 내용 가져오기 소스 짜기)


<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<script>

// dom node 구조 접근시 편하게 사용하기 위한 jquery 스타일의 함수

function $(id) {

return document.getElementById(id);

}

window.onload = function() {

search();

}

function search() {

$("results").innerHTML = "";

// 검색문자열

var keyword = "kkang";

// callback : 검색 결과를 process로 받을 수 있는 개발자 함수

var query   = "http://search.twitter.com/search.json?callback=process"

                    + "&q=";

query += encodeURI(keyword);

// 존재하지 않는 script tag를 만들어 사용하겠다

var script = document.createElement("script");

script.src = query;

// 만들어진 tag를 헤드테그의 자식노드에 붙임, 바뀐 head 정보에 의해 페이지가 열림

document.getElementsByTagName("head")[0].appendChild(script);

}

// twitter 검색결과를 callback 으로로 지정한 process 펑션으로  핸들링

function process(response) {

var datas = response.results;

// map : 집합객체의 갯수만큼 지정된 함수를 호출(하나하나 넘김)

var rows  = datas.map(function(data) {

// 한 건의 데이터로 화면에 찍어주기 위한 html 구조를 만들어 주는 함수 호출

return createResult(data.profile_image_url, data.text);

});

// 화면 출력

rows.forEach(function(row) {

$("results").appendChild(row);

});

}

// 넘어온 데이터로 화면에 찍을 html 구조를 완성하는 함수

function createResult(src, title) {

var p    = document.createElement("p");

var icon = document.createElement("img");

icon.src = src;

icon.setAttribute("width" , 48);

icon.setAttribute("height", 48);

// p 테그 속에 img 테그를 넣고 문자열로 만듬

p.appendChild(icon);

p.appendChild(document.createTextNode(title));

return p;

}

</script>

</head>

<body>

    <div id="results"></div>

</body>

</html>


05. 검색결과 확인 (설정한 도메인으로 검색결과를 확인한다)




본격적인 crocess document 테스트


inner.html

<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<script>

// dom node 구조 접근시 편하게 사용하기 위한 jquery 스타일의 함수

function $(id) {

return document.getElementById(id);

}

// outter에서 넘어오는 MessageEvent 시 호출될 함수

function messageHandler(e) {

if (e.origin == "http://localhost:8080") {

search(e.data);

}

}

window.onload = function() {

//search();

// message 이벤트가 발생했다면 messageHandler함수를 호출하라

window.addEventListener("message", messageHandler);

}

function search(keyword) {

$("results").innerHTML = "";

// 검색문자열

//var keyword = "kkang";

// callback : 검색 결과를 process로 받을 수 있는 개발자 함수

var query   = "http://search.twitter.com/search.json?callback=process"

                    + "&q=";

query += encodeURI(keyword);

// 존재하지 않는 script tag를 만들어 사용하겠다

var script = document.createElement("script");

script.src = query;

// 만들어진 tag를 헤드테그의 자식노드에 붙임, 바뀐 head 정보에 의해 페이지가 열림

document.getElementsByTagName("head")[0].appendChild(script);

}

// twitter 검색결과를 callback 으로로 지정한 process 펑션으로  핸들링

function process(response) {

var datas = response.results;

// map : 집합객체의 갯수만큼 지정된 함수를 호출(하나하나 넘김)

var rows  = datas.map(function(data) {

// 한 건의 데이터로 화면에 찍어주기 위한 html 구조를 만들어 주는 함수 호출

return createResult(data.profile_image_url, data.text);

});

// 화면 출력

rows.forEach(function(row) {

$("results").appendChild(row);

});

}

// 넘어온 데이터로 화면에 찍을 html 구조를 완성하는 함수

function createResult(src, title) {

var p    = document.createElement("p");

var icon = document.createElement("img");

icon.src = src;

icon.setAttribute("width" , 48);

icon.setAttribute("height", 48);

// p 테그 속에 img 테그를 넣고 문자열로 만듬

p.appendChild(icon);

p.appendChild(document.createTextNode(title));

return p;

}

</script>

</head>

<body>

    <div id="results"></div>

</body>

</html>


outter.html

<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<style>

iframe {

width : 800px;

height: 400px;

}

</style>

<script>

window.onload = function() {

var searchBtn = document.getElementById("searchBtn");

searchBtn.addEventListener("click", search);

}

function search() {

var searchTxt = document.getElementById("keyword").value;

// Cross Document 로 데이터 전송

document.getElementById("inner").contentWindow.postMessage(searchTxt, "http://www.test.com:8080");

}

</script>

</head>

<body>

<p>

    keywork : <input type="text" id="keyword" width="500">

<button id="searchBtn">search</button>

</p>

<p>

<iframe id="inner" src="http://www.test.com:8080/Ch4-Communication/inner.html"></iframe>

</p>

</body>

</html>


결과 : outter.html (http://localhost:8080/Ch4-Communication/outter.html) 을 실행시켜 

         inner.html (http://www.test.com:8080/Ch4-Communication/inner.html) 에서 결과가 나오는 것을 확인한다


         로컬 주소를 통하여 www.test.com:8080 에서 실행된 검색 결과를 가져온다.

         document.getElementById("inner").contentWindow.postMessage(searchTxt, "http://www.test.com:8080");

         로 인하여 가능





--------------------------------
-----------------------------------------------------------------



----------------------------------------------------------------

CANVAS

----------------------------------------------------------------


canvas : pixel

SVG     : vector (http://svg-wow.org/)



----------------------------------------------------------------

VIDEO Control (안드로이드와 타브라우저의 동작이 상이하므로 주의할것)

----------------------------------------------------------------


01. 프로젝트를 Dynamic Web Project 로 생성 하여 video.html 파일 실장


<!DOCTYPE html>

<html>

<head>

<meta charset=EUC-KR">

<title>Insert title here</title>

<script>

var video;

window.onload = function() {

var device;

video = document.getElementById("video");

//*******************************************

// user agent 값으로 현 디바이스의 정보를 뽑아냄

//*******************************************

var agent = navigator.userAgent;

if (agent.toUpperCase().indexOf("IPHONE") > -1) {

device = "iPhone";

} else if (agent.toUpperCase().indexOf("ANDROID") > -1) {

device = "Android";

// Android4.0 ICS 폰(2012.03월 현재 최신버전)에서의 브라우저는

// html5 video play 를 테스크탑 브라우저와 동일 방법으로 처리

if (agent.toUpperCase().indexOf("ANDROID 4.0") > -1) {

device = "Android4.0";

}

} else {

device = "unKnown";

}

//*********************************************************

// 중요 : 안드로이드용은 컨트롤바를 빼야함, 소스의 타입을 빼야함

//*********************************************************

if (device == "Android") {

var videodiv = document.getElementById("myvideo");

videodiv.innerHTML = "<video id='video' poster='bbb_poster-360x240.jpg' width='360' height='240'>"

                               + "    <source src='BigBuck.m4v'        />"

                               + "    <source src='BigBuck.webm'       />"

                               + "    <source src='BigBuck.theora.ogv' />"

  + "</video>"

  + "<p><input type='button' onClick='play()' value='play' /></p>";

}

}

    

    function play(){

        video.play();

    }

</script>

</head>

<body>

<!-- -----------------------------------------------------

          데스크탑 브라우저나 iPhone 에서느 아래와 같이 정상 play됨

안드로이드의 경우는 source type에 명시되어 있으면 안되고

반드시 javascript에서 play 명령을 내려야 함

------------------------------------------------------ -->

    <div id="myvideo">

        <video id="video" poster="bbb_poster-360x240.jpg" width="360" height="240" controls>

    <source src="BigBuck.m4v"        type="video/mp4" />

            <source src="BigBuck.webm"       type="video/webm" />

            <source src="BigBuck.theora.ogv" type="video/ogg" />

    </video>

    </div>

</body>

</html>



02. 확인