둘은 똑같이 Mobile JavaScript Library라는 공통점을 지니고 있지만, 개발에 사용되는 언어의 차이가 크다.
jQuery Mobile은 기존 HTML 개발하듯이 마크업 중심의 구성을 갖고 있으며, Sencha Touch는
JavaScript로 개발을 하는데 특히 ExtJS 라이브러리 중심으로 구성되어 있다. 이는 개발 난이도를 결정하는 요소가 된다.
ExtJS 라이브러리를 다룰 수 있는 개발자가 거의 없기에(외국에도 많이 쓰이지는 않는다.) ExtJS를 먼저 학습해야 하는
비용이 추가된다. 그에 반해 jQuery Mobile은 우리에게 익숙한 HTML 중심의 마크업 언어라서 잠깐의 교육만으로도 바로
개발이 가능하다.
실무에 어떤 라이브러리를 선택할 것인가?
"개발방시의 차이"는 때때로 인력 구성의 심각한 문제를 가져 올 수 있다. 미래웹기술연구소에서 수행했던 프로젝트의 경우
디자이너/Web UI Developer(HTML/CSS 코딩)/자바스크립트 엔지니어 이렇게 분업이 잘 되어 있다. Web UI
Developer 가 없는 프로젝트에서는 디자이너가 HTML/CSS 코딩 역할을 대신 하기도 한다. 그러나 Sencha Touch
중심의 웹앱 프로젝트에서는 Web UI Developer가 Sencha Touch나 ExtJS를 모르면 아무런 작업을 할 수
없다. 그렇게 Web UI Developer가 하지 못한 작업들은 고스란히 자바스크립트 엔지니어에게 전가 된다.(하지만 전달받은
개발자 또한 ExtJS 라이브러리가 익숙한 것은 아닐 것이다.) 그래서 웹앱개발을 위한 자바스크립트 라이브러리 선택시에는 현재
조직의 인원구성에 대한 고민이 선행되어야 한다.
하이브리드 앱
두가지 라이브러리 모두 PhoneGap 등을 이용하여 앱(App.)으로 만들 수 있다. 하지만 이부분에서 Sencha
Touch의 앱 스러움이 실력을 발휘 한다. 일단 언어가 비슷하고 (Sencha Touch와 PhoneGap 모두 자바스크립트
기반) 마크업언어와 다르게 콤포넌트 기반이어서 화면 구성이 앱과 비슷한 점이 많다. 그리고 앱스러운 기능을 jQuery
Mobile 보다 월등하게 많이 가지고 있다.
A quick and simple service for getting pictures of kittens for use as
placeholders in your designs or code. Just put your image size (width
& height) after our URL and you’ll get a placeholder.
Follow the placekitten.com url with your desired dimensions. For
example, if I needed a 450 x 300 placeholder image, I’d set the source attribute of an image tag to: http://placekitten.com/450/300.
Note that, with this service, you set your dimensions more traditionally, rather than separating the widths and heights into segments.
Placehold.it is a bit different in that, rather than using photos
for placeholders, it instead uses more traditional solid color images,
which might be more appealing to some designers.
Add some Sheen to your designs and prototypes with Charlie Sheen
placeholder pictures. Simply change the width and height in the URL to
get your custom placeholder.
Get placeholders related to the site you are developing, by pulling images from flickr based on tags.
Usage
FlickrHolder is helpful in that, in addition to using Flickr photos
as the placeholders, it also allows you to choose a desired tag as the
third segment. You can even choose to display photos in black and white.
DummyImage is particularly nice, when compared to some of its
competitors, in that it offers a great deal of flexibility. Let’s take a
look at some of the available options.
A clean and simple way to help align your layouts. No complex grid frameworks necessary.
Certainly, Griddle.it is unique compared to its peers because its
focus is on creating grid images, which can then be applied to the
background of your web design during production. View a live demo here.
Usage
Applying a background grid requires the following format: http://griddle.it/[total width]-[number of columns]-[gutter size].
# 예제 따라해보았다.
완전 시행착오 많이 하고. Ant 를 Eclipse와 연동해서 build 는 하는데, 이클립스에 이미 Ant가 플러그인되어 있는데 새로 내려받은거와 연동을 해서 혼선이 있었다. SDK 다 내려받고, web.xml 만들고 경로 연동에서 잘 해주어야 한다. Ant 빌드파일 생성 시 <property name="sdk.dir" location="../appengine-java-sdk-1.4.3" /> 라고 있는데, 실제 appengine 경로에 연결을 잘 해야 한다. 소스만 보고 따라하면 안됨. 이클립스에서 실행이 안되서(나의 설정잘못이겟지만. 아무튼.), 도스창으로 들어가서 > ant runserver 를 실행하고 나서야 웹페이지에서 확인할 수 있었다. ant 를 도스창에서 사용할면 환경변수에 ANT_HOME 과 Path에 %ANT_HOME%/bin 을 잊지마라.
Google App Engine lets you run your web applications on Google's
infrastructure. App Engine applications are easy to build, easy to
maintain, and easy to scale as your traffic and data storage needs grow.
With App Engine, there are no servers to maintain: You just upload your
application, and it's ready to serve your users.
You can serve your app from your own domain name (such as http://www.example.com/) using Google Apps. Or, you can serve your app using a free name on the appspot.com domain. You can share your application with the world, or limit access to members of your organization.
Google App Engine supports apps written in several programming
languages. With App Engine's Java runtime environment, you can build
your app using standard Java technologies, including the JVM, Java
servlets, and the Java programming language—or any other language using a
JVM-based interpreter or compiler, such as JavaScript or Ruby. App
Engine also features a dedicated Python runtime environment, which
includes a fast Python interpreter and the Python standard library. The
Java and Python runtime environments are built to ensure that your
application runs quickly, securely, and without interference from other
apps on the system.
With App Engine, you only pay for what you use. There are no set-up
costs and no recurring fees. The resources your application uses, such
as storage and bandwidth, are measured by the gigabyte, and billed at
competitive rates. You control the maximum amounts of resources your app
can consume, so it always stays within your budget.
App Engine costs nothing to get started. All applications can use up
to 500 MB of storage and enough CPU and bandwidth to support an
efficient app serving around 5 million page views a month, absolutely
free. When you enable billing for your application, your free limits are
raised, and you only pay for resources you use above the free levels.
이미 사용 중인 Eclipse에 Appspresso를 통합할 수 있는 Appspresso Eclipse plug-in의 설치 URL은 다음과 같습니다. (plug-in 설치 방법은 사용 중인 Eclipse의 도움말을 참조하시기 바랍니다.) http://www.appspresso.com/update/site.xml
※ Appspresso 1.0 beta에서 생성한 project를 beta2로 이전하기 Appspresso 1.0 beta2에서 변경사항이 있어 Appspresso 1.0 beta에서 생성한 Appspresso project를 인식하지 못합니다. 해당 project를 Appspresso 1.0 beta2에서 인식되게 하려면 파일 탐색기를 통해 Appspresso project 폴더로 이동하신 후 .project 파일을 찾아 텍스트 편집기로 열고 다음과 같이 수정해 주시기 바랍니다. Appspresso 1.0 beta : <nature>com.kthcorp.wp.rudder.core.Nature</nature> Appspresso 1.0 beta2: <nature>com.appsresso.core.Nature</nature>
HTML5 offers two new objects for storing data on the client: * localStorage - stores data with no time limit * sessionStorage - stores data for one session
Client-Side 데이터 기억장치 : 초기에 웹 애플리켕이션에서는 데이터저장을 서버측 데이터베이스나 브라우저 쿠키가 담당했지만, HTML5의 등장으로 웹 개발자들은 더 많은 선택의 여지가 생겼는데 그것은 localStorage, sessionStorage, client-side databases.
localstorage와 sessionStorage는 다수의 페이지들을 검색할 때 name/value 쌍을 설정하기 위해 javascript를 사용한다는 점에서 쿠키와 매우 유사하다. 하지만, 쿠키와 달리 부라우저이 요청이 있을 때 데이터를 와이어를 통해 전송하지 않는데, 데이터는 오직 클라이언트에만 존재한다. 그러므로 쿠키보다 더 많은 데이터를 저장하는 것이 가능하다.
이 둘은 기능적으로는 같지만, 지속성과 범위 측면에서만 다르다.
localStorage - 윈도우가 닫힌 후에도 데이터가 저장된다. 데이터는 같은 소스(도메인네임,프로토콜, 포트가 같아야 한다.)로부터 로드된 모든 윈도우에서 사용 가능하다. 이는 애플리케이션 환경설정 같은 것에 유용하다. sessionStorage - 데이터는 윈도우객체와 함께 저장된다. 다른 윈도우(or Tab)들은 데이터 값을 알지 못하고 윈도우가 닫힐때 사라진다. 활성화된 탭을 강조하는 것과 같은 윈도우의 특정 상태만을 저장할 때나 테이블 정렬 순서를 저장할 때 유용하다.
value 설정 : localStorage.setItem('age', 35); 저장된 value 호출 : var age = localStorage.getItem('age'); 특정한 key/value 삭제하기 : localStorage.removeItem(age); 모든 key/value 삭제하기 : localStorage.clear();
ex) kilo.js var db; var jQT = $.jQTouch({ icon: 'kilo.png', statusBar: 'black' });
//shortName : 디스크에 있는 database를 호출하기 위해 몇 개의 var을 정의하고 있다. var shortName = 'Kilo'; // version : Database 스키마를 바꿀 필요가 있을 경우, // 업그레이드와 이전 버전과의 호환을 처리하기 위해 사용한다. var version = '1.0'; // displayName : 사용자 인터페이스에 보이는 문자열 // 예를 들어 아이폰에 있는 Setting 애플레케이션에서 // Setting > Safari > Database panel 에 displayName이 보인다. var displayName = 'Kilo'; //Database 가 가지는 최대 크기를 킬로바이트 단위로 지정한다. var maxSize = 65536; //위 설정된 파라미터를 가지고 openDatabase 함수를 호출하고 연결을 db변수에 저장한다. // 만약 Open 하고자 하는 database가 존재하지 않으면 새로 생성한다. db = openDatabase(shortName, version, displayName, maxSize); // transaction 메서드를 호출. db.transaction( //익명 함수를 사용하여 파라미터로 트랜잭션을 전달한다. function(transaction) { // 함수 내부에서 표준 CREATE TABLE 쿼리를 실행하기 위해 // 트랜잭션 객체의 excuteSql메서드를 호출한다. transaction.executeSql( 'CREATE TABLE IF NOT EXISTS entries ' + ' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' + ' date DATE NOT NULL, food TEXT NOT NULL, ' + ' calories INTEGER NOT NULL );' ); } ); });
function loadSettings() { $('#age').val(localStorage.age); $('#budget').val(localStorage.budget); $('#weight').val(localStorage.weight); }
function refreshEntries() { var currentDate = sessionStorage.currentDate; $('#date h1').text(currentDate); $('#date ul li:gt(0)').remove(); db.transaction( function(transaction) { transaction.executeSql( 'SELECT * FROM entries WHERE date = ? ORDER BY food;', [currentDate], function (transaction, result) { for (var i=0; i < result.rows.length; i++) { var row = result.rows.item(i); var newEntryRow = $('#entryTemplate').clone(); newEntryRow.removeAttr('id'); newEntryRow.removeAttr('style'); newEntryRow.data('entryId', row.id); newEntryRow.appendTo('#date ul'); newEntryRow.find('.label').text(row.food); newEntryRow.find('.calories').text(row.calories); newEntryRow.find('.delete').click(function(){ var clickedEntry = $(this).parent(); var clickedEntryId = clickedEntry.data('entryId'); deleteEntryById(clickedEntryId); clickedEntry.slideUp(); }); } }, errorHandler ); } ); } function createEntry() { // SQL에 사용할 변수를 설정한다. var date = sessionStorage.currentDate; var calories = $('#calories').val(); var food = $('#food').val(); db.transaction( function(transaction) { transaction.executeSql( // ?는 플래이스 홀더(자리표시)이다. 'INSERT INTO entries (date, calories, food) VALUES (?, ?, ?);', // Database에 전송될 값들의 배열. // place holder에 대응되는 값이다. [date, calories, food], // 이 익명함수는 SQL쿼리가 성공하면 실행된다. function(){ refreshEntries(); jQT.goBack(); }, // SQL 쿼리가 실패하면 실행될 함수 이름이다. errorHandler ); } ); return false; }
// Entry 삽입이 실패하면 실행. // 에러 핸들러는 두개의 파라미터가 전송된다. 트랜잭션 객체와 에러 객체이다. // error 핸들러는 true 나 false 를 반환한다. // 에러핸들러가 true를 반환할 때는 실행이 멈추고 전체 트랜잭션이 RollBack 한다. // " false를 반환할 때는 계속 실행. // ERROR Code // Constant Code Situation // UNKNOWN_ERR 0 트랜잭션실패.Database자체와는 무관하고, 다른 오류코드에 포함되지 않는다. // DATABASE_ERR 1 Statement 실패 // VERSION_ERR 2 Operation 실패. 버전이 다르다. // TOO_LARGE_ERR 3 Statement 실패. DB에서 리턴된 데이터가 너무 크다.SQL LIMIT modifier권유 // QUOTA_ERR 4 Statement 실패. 남아있는 공간이 충분하지 않거나 저장공간 할당량 초과. // SYNTAX_ERR 5 Statement 실패. Syntax 에러,파라미터의 수가 맞지 않거나, 허용되지 않는 문자열 시도 // CONSTRAINT_ERR 6 Constraint 실패로 인해 insert, update, replace statement 실패 // TIMEOUT_ERR 7 Transaction을 위한 lock이 주어진 시간을 초과하였다. function errorHandler(transaction, error) { alert('Oops. Error was '+error.message+' (Code '+error.code+')'); return true; }
function deleteEntryById(id) { db.transaction( function (transaction) { transaction.executeSql('DELETE FROM entries WHERE id=?;', [id], null, errorHandler); } ); }
The HTML5 Web Sockets specification defines an API
that enables web pages to use the Web Sockets protocol for two-way
communication with a remote host. It introduces the WebSocket
interface and defines a full-duplex communication channel that operates
through a single socket over the Web. HTML5 Web Sockets provide an
enormous reduction in unnecessary network traffic and latency compared
to the unscalable polling and long-polling solutions that were used to
simulate a full-duplex connection by maintaining two connections.
HTML5 Web Sockets account for network
hazards such as proxies and firewalls, making streaming possible over
any connection, and with the ability to support upstream and downstream
communications over a single connection, HTML5 Web Sockets-based
applications place less burden on servers, allowing existing machines
to support more concurrent connections. The following figure shows a
basic WebSocket-based architecture in which browsers use a WebSocket
connection for full-duplex, direct communication with remote hosts.
The idea for the site came about following an HTML5 meetup after 2009′s Future of Web Design
conference in London. We realized there wasn’t a resource for people
who wanted to learn more about the hows and whys of implementing HTML5, so we decided to build one!
Originally, there were five of us (Rich, Bruce, Jack, Mike, and Tom).
Shortly before launch, Remy came on board too. Then in early 2010, Oli
made us an offer we couldn’t refuse, and we became seven.
We’d also like to offer a massive thank you to Brandan Lennox,
who has been copy editing our posts for some time now. Brandan does a
superb job of editing our articles and making them easy to read.
Our Aims
We will publish articles relating to HTML5, its semantics, and how to use it right now. We also invite questions via Ask the Doctor. We’ll post answers in future articles so that everyone can benefit.
We acknowledge that we may sometimes get things wrong and that people may disagree with our interpretation of the HTML5 specification.
But that’s another of the reasons that this site exists: the spec has
yet to be formalised, and we can all do our bit to make it what we want.
A “specification for the people” if you will.
Get involved
We invite you to freely comment, question, congratulate, argue, and
suggest in the articles’ comments sections, and we’ll do our best to
answer in a considered and reasoned manner. As we said above, the HTML5 specification has yet to be finalised, so we can all have a say, and we invite you to do so here on our site.
We hope you find HTML5 Doctor a useful resource. If you have any questions relating to HTML5 and how to implement it, just ask the doctor!