반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

JQuery Mobile - Navbar

2012. 7. 25. 00:06 | Posted by 솔웅


반응형

Simple navbar


jQuery Mobile은 아주 기본적인 navbar 위젯을 가지고 있습니다. 하나의 바에 optional icons와 함께 다섯개의 버튼을 표시할 수 있습니다. 또한 persistent navbar variation 도 있는데요. 페이지 이동시에도 고정돼 있는 탭 바와 비슷합니다.


navbar는 data-role="navbar" attribute 를 가지고 있는 container element 안에 싸여있는 링크들의 정렬되지 않은 리스트로 코딩 됩니다. 아래에는 두개의 버튼이 있는 navbar에 대한 예제입니다.



<div data-role="navbar">
	<ul>
		<li><a href="a.html">One</a></li>
		<li><a href="b.html">Two</a></li>
	</ul>
</div><!-- /navbar -->


navbar에 있는 링크가 클릭되면 active(selected) 상태가 됩니다. ui-btn-active 클래스는 activated link에 추가되기 전에 navbar 에 있는 모든 anchor들로부터 첫번재로 remove 됩니다. 만약에 이 링크가 다른 페이지로 가는 링크라면 이 클래스는 transition이 완료된 이후에 다시 remove 됩니다.

navbar가 initialization 되고 그곳의 아이템을 active state로 세팅하기 위해서는 class="ui-btn-active" 를 여러분 markup의 해당 anchor에 추가하시면 됩니다. 추가적으로 ui-state-persist를 넣으시면 framework는 그 정보가 DOM에 있는 한 페이지가 보일때마다 active state를 restore 합니다. 예제 파일의 첫번째 예제는 "One"을 active 상태로 세팅 한 navbar를 보여 줍니다.



<div data-role="navbar">
	<ul>
		<li><a href="a.html" class="ui-btn-active ui-state-persist">One</a></li>
		<li><a href="b.html">Two</a></li>
	</ul>
</div><!-- /navbar -->



이 경우 navbar 아이템들은 공간을 균등하게 나눠 갖습니다. 각 버튼은 브라우저 윈도우의 1/2씩을 차지 합니다.



navbar01.html





위에 보시는 대로 3번째 아이템을 추가하면 자동적으로 1/3씩 아이템이 공간을 차지합니다.
4개를 배치하면 1/4, 5개를 배치하면 1/5씩 공간을 차지합니다.

navbar의 최대 아이템 수는 5개까지 입니다.


만약 아이템이 5개 이상이면 navbar는 줄을 바꿔서 표시됩니다.


아이템이 1개만 있으면 이 아이템은 100%의 width 를 차지하게 됩니다.

위 예제 파일을 다운 받으신 후 실행해 보시면 직접 눈으로 확인 하실 수 있습니다.


Navbars in headers


navbar를 페이지의 top에 추가하시게 되면 페이지 타이틀과 버튼은 계속 남아 있게 됩니다. navbar를 header block 안에 넣으세요. 바로 타이틀과 버튼 다음에요. 그러면 navbar를 top에 (title 바로 다음 줄에) 표시할 수 있습니다.


Navbars in footers


페이지의 bottom에 navbar를 추가하시면 어떻게 될까요? tab bar 처럼 보이겠죠. data-role="footer" 와 함께 콘테이너에 navbar를 넣어 주세요.


<div data-role="footer">		
	<div data-role="navbar">
		<ul>
			<li><a href="#">One</a></li>
			<li><a href="#">Two</a></li>
			<li><a href="#">Three</a></li>
		</ul>
	</div><!-- /navbar -->
</div><!-- /footer -->


Icons in navbars


data-icon attribute를 추가하면 navbar에 아이콘도 넣을 수 있습니다. 각 anchor에 standard mobile icon을 추가할 수 있습니다. 디폴트로 아이콘은 텍스트 위쪽에 위치됩니다. (data-iconpos="top"). 아래 예제는 footer 안에 있는 navbar에 아아콘을 추가하는 예제입니다.


아이콘은 visual consistency를 위해 각각의 링크에 다는 대신 on the navbar container 에 세팅합니다.


<div data-role="navbar" data-iconpos="bottom">

이 예제는 bottom에 icon이 위치되게 됩니다.

아이콘 포지션은 data-iconpos="left" 와 data-iconpos="right"로 세팅될 수 있습니다.

결과 화면은 첨부 파일을 참조하세요.


Using 3rd party icon sets


여러분은 텍스트 label의 위에 있는 큰 아이콘을 갖는 iOS 스타일의 탭을 표현할 수 있는 Glyphish 같은 인기있는 아이콘 라이브러리를 추가할 수도 있습니다. 그러기 위해 필요한 것은 이 아이콘을 표시하기 위한 링크를 걸고 navbar에 위치를 지정하는 것 뿐입니다. 

아래 이미지는 navbar에 Glyphish icons 를 이용해서 custom style을 구현한 예제입니다.




Icons by Joseph Wain / glyphish.com. Licensed under the Creative Commons Attribution 3.0 United States License.


Theming navbars


navbar는 parent container로부터 theme swatch를 상속받습니다. (버튼을 상속 받는 것 처럼요.) navbar가 header나 footer에 위치해 있으면 디폴트 툴바 swatch "a" 를 상속 받을 겁니다. 

샘플 파일을 다운 받아 보시면 몇가지 예제를 보실 수 있을 겁니다. 자동적으로 parent's swatch letter를 상속한 겁니다. 이 에제에서는 data-theme attribute를 사용하는 대신에 body swatch(ui-body-a)에 적용하기 위해 manual로  swatch 클래스를 추가했습니다. 이런 경우에도 상속은 같은 방법으로 이루어 집니다.


navbar 아이템에 theme color를 세팅하려면 각각의 link에 data-theme attribute를 추가시고 특정 theme swatch를 지정해 주시면 됩니다. navbar container에 theme swatch를 적용하는 것은 지원되지 않습니다.



반응형

'jQuery Mobile > JQM Tutorial' 카테고리의 다른 글

JQuery Mobile - Theming Toolbars  (0) 2012.08.07
JQuery Mobile - Persistence Toolbars  (0) 2012.07.29
JQuery Mobile - Fixed toolbar Methods/Events  (0) 2012.07.29
JQuery Mobile - Fixed toolbar options  (0) 2012.07.29
Fixed toolbars  (0) 2012.07.28
JQuery Mobile - Footers  (0) 2012.07.24
JQuery Mobile - Header structure  (0) 2012.07.23
JQuery Mobile - Toolbar types  (0) 2012.07.21
JQuery Mobile - Theming Page  (0) 2012.07.12
JQuery Mobile - touchOverflow 기능  (0) 2012.07.09

JQuery Mobile - Footers

2012. 7. 24. 05:52 | Posted by 솔웅


반응형

Footer bar structure


footer bar는 data-role attribute 값에footer를 넣는 다는 것 말고는 header와 기본 구조가 같습니다.


<div data-role="footer"> 
	<h4>Footer content</h4> 
</div> 



footer toolbar는 디폴트로 a swatch를 theme으로 사용할 겁니다. 이것은 여러분이 쉽게 set the theme swatch color를 할 수 있습니다.


page footer는 옵션과 configuration 관련해서는 헤더와 아주 유사합니다. 가장 크게 다른 부분은 footer는 헤더보다 그 기능이 적다는 겁니다. 특히 구조와 관련해서요. 그래서 framework는 헤더에 자동적으로 적용했던 왼쪽 오른쪽의 버튼을 위한 slot을 제공하지 않습니다.

footer는 이렇게 헤더처럼 미리 그 구조가 짜여져 있지 않기 때문에 여러분이 원하는 디자인 구조를 적용하시려면 grids layout과 custom style을 사용할 것을 권합니다.


Adding buttons

footer에 링크나 button markup 을 추가하면 둘 다 모두 자동적으로 button으로 표시 됩니다. 공간을 절약하기 위해 툴바에 있는 버튼들은 자동적으로 inline styling로 세팅됩니다. 그러니까 그 버튼은 그 안의 텍스트나 아이콘의 너비 만큼 공간을 차지하게 됩니다.

디폴트로 툴바는 nav bar 나 다른 위젯 공간을 위한 padding을 가지고 있지 않습니다. bar에 padding을 넣으려면 class="ui-bar" 를 footer에 추가해야 합니다.


<div data-role="footer" class="ui-bar">
	<a href="index.html" data-role="button" data-icon="plus">Add</a>
	<a href="index.html" data-role="button" data-icon="arrow-u">Up</a>
	<a href="index.html" data-role="button" data-icon="arrow-d">Down</a>
</div>


이 예제는 좌우로 버튼을 한줄 정렬해서 표시하게 됩니다.

아래 예제 파일 다운 받으셔서 소스도 고치시면서 직접 눈으로 확인하시면 더 이해가 쉽게 갈겁니다.


footer01.html




.ui-bar는 페이지의 full width로 하기 위해 헤더나 footer에 추가하시면 안됩니다. 추가적인 padding은 parent container의 full-width element를 break 할 겁니다. full-width toolbar 안에 padding을 추가하려면 element 안에 툴바의 contents를 감싸고 이 padding을 그 element에 추가하세요.

버튼들을 하나의 그룹으로 묶으려면 wrapper 안에 있는 링크들을 data-role="controlgroup",data-type="horizontal" attributes 와 함께 감싸세요.


<div data-role="controlgroup" data-type="horizontal">


이렇게 하면 버튼 그룹을 만들 수 있습니다. 위 예제 파일을 확인해 보세요.



Adding form elements

Forms elements 와 다른 content들도 또한 toolbar에 add될 수 있습니다. 위 예제 파일에 footer bar 안의 select menu 예제가 있습니다. data-mini="true" attribute를 추가해서 툴바 안에 mini-sized form elements를 사용할 것을 권장합니다.


Fixed & Persistent footers

footer가 global navigation element인 경우 여러분은 화면이 스크롤 될 때 따라 움직이지 않고 제자리에 표시 되도록  fixed 로 display 하기를 원하실 겁니다.  fixed toolbar persistent도 가능합니다. 이런 경우에는 page transitions이 일어나도 그 툴바는 계속 보일 겁니다. 이 기능은 jQuery Mobile에 포함돼 있는 persistent footer feature를 사용함으로서 구현하실 수 있습니다.


화면전환에도 footer를 계속 보이게 하려면 관계된 모든 페이지의 footer에 data-id attribute를 추가하세요. 물론 id 값은 모두 같아야 합니다. 예를 들어 현재페이지와 다음(target) 페이지에 data-id="myfooter"를 추가하면 framework은 page가 바뀌는 동안에도 같은 지점에 footer를 계속 고정시킬것입니다.

이 기능은 header와 footer가 data-position="fixed"로 세팅돼 있을 때에만 제대로 작동할 겁니다. 그렇게 하면 transition 동안에도 계속 보이게 됩니다.

반응형

'jQuery Mobile > JQM Tutorial' 카테고리의 다른 글

JQuery Mobile - Persistence Toolbars  (0) 2012.07.29
JQuery Mobile - Fixed toolbar Methods/Events  (0) 2012.07.29
JQuery Mobile - Fixed toolbar options  (0) 2012.07.29
Fixed toolbars  (0) 2012.07.28
JQuery Mobile - Navbar  (2) 2012.07.25
JQuery Mobile - Header structure  (0) 2012.07.23
JQuery Mobile - Toolbar types  (0) 2012.07.21
JQuery Mobile - Theming Page  (0) 2012.07.12
JQuery Mobile - touchOverflow 기능  (0) 2012.07.09
JQuery Mobile - PhoneGap apps  (1) 2012.07.09

JQuery Mobile - Header structure

2012. 7. 23. 07:54 | Posted by 솔웅


반응형

Header structure


헤더는 대개 페이지 윗부분에 위치하며 페이지 타이틀이 표시되거나 왼쪽이나 오른쪽에 버튼이 있어 이전 이후 페이지로 가도록 하는 기능을 제공하는 툴 바입니다. 헤더는 선택에 따라 fixed로 포지션 될 수 있으며 일러 경우 페이지가 스크롤링 될 때 같이 되지 않고 항상 top 에 위치해 있게 됩니다.


타이틀 글자는 대기 H2 heading element를 사용하지만 H1에서 H6까지 여러분들 선택에 따라 사용하실 수 있습니다. 예를 들어 모바일 페이지에는 여러 페이지들이 있을 수 있고 그 중 home page에는 H1을 그 다음 secondary page에는 H2 element를 사용하실 수 있겠죠. 모든 헤딩 레벨은 시각적인 일관성을 주기 위해 styled 되면 더 좋습니다.


<div data-role="header"> 
	<h1>Page Title</h1> 
</div> 


header01.html

예제들은 위 파일을 받아 보시면 있습니다.

이 블로그에서는 실행이 안되서 따로 파일을 만들었습니다.

이 파일을 실행시키면 아래와 같은 화면을 보실 수 있습니다.

다운 받아서 직접 실행해 보시고 소스도 이것저것 바꿔보세요.


Default header features


헤더 툴바는 디폴트로 a swatch로 theme 돼 있습니다. 하지만 여러분이 원하시면 쉽게 theme swatch color 를 하실 수 있습니다.


예제는 이 글 맨 밑에 있는 첨부파일을 보시면 있습니다.


Adding buttons


표준 헤더 configuration에서 텍스트 헤딩 양쪽에 button들을 위한 slot이 있습니다. 각 버튼들은 anchor element이구요 어떤 button markup이든지 사용하실 수 있습니다. 공간을 절약하기 위해서 툴바에 있는 버튼들은 inline styling로 세팅하세요. 그러면 버튼 크기가 자동적으로 그 버튼안에 있는 텍스트와 아이콘의 크기에 맞게 세팅될 겁니다.


Default button positioning


헤더 플러그인은 헤더 콘테이너의 직속 children이라고 할 수 있습니다. 첫번째 링크는 자동적으로 왼쪽 버튼 slot에 세팅을 하고 두번째 링크는 오른쪽에 세팅합니다. 아래 예제에서 Cancel 버튼은 왼쪽 slot에 나타날 것이고 Save는 오른쪽 slot에 나타날 겁니다.


<div data-role="header" data-position="inline">
	<a href="index.html" data-icon="delete">Cancel</a>
	<h1>Edit Contact</h1>
	<a href="index.html" data-icon="check">Save</a>
</div>


Making buttons visually stand out


Buttons automatically adopt the swatch color of the bar they sit in, so a link in a header bar with the "a" color will also be styled as "a" colored buttons. It's simple to make a button visually stand out. Here, we add the data-theme attribute and set the color swatch for the button to "b" to make the "Save" button pop.


<div data-role="header" data-position="inline">
  <a href="index.html" data-icon="delete">Cancel</a>
  <h1>Edit Contact</h1>
  <a href="index.html" data-icon="check" data-theme="b">Save</a>
</div>

Controlling button position with classes


버튼의 위치는 버튼 anchor에 class를 add 함으로서 콘트롤 될 수 있습니다. (이 경우에는 소스의 순서가 아니라 설정된 클래스에 따라 위치가 정해지겠죠.) 아래 경우에는 1개의 버튼을 오른쪽에 표시하고 싶을 때 사용하실 수 있을 겁니다. 버튼의 위치를 정하시려면 ui-btn-leftui-btn-right 클래스를 anchor에 넣어 주세요.


<div data-role="header" data-position="inline"> 
	<h1>Page Title</h1>
	<a href="index.html" data-icon="gear" class="ui-btn-right">Options</a>
</div>


Adding buttons to toolbars without heading


헤더바 안의 헤딩은 약간의 margin을 가지고 있습니다. 이 마진은 bar의 height을 나타냅니다. 헤딩을 사용하지 않는다면 class="ui-title" 와 함께 element를 추가하셔야 합니다. 그러면 그 바는 hight를 얻어서 정확하게 display 할 수 있을 겁니다.


<div data-role="header" data-position="inline"> 
	<a href="index.html" data-icon="gear" class="ui-btn-right">Options</a>
	<span class="ui-title" />
</div>


Adding Back buttons


jQuery Mobile은 어떤 헤더에건 자동적으로 back 버튼을 생성하고 추가할 수 있는 기능이 있습니다. 디폴트로는 이 기능이 disabled 돼 있습니다. 이 경우는 chromeless installed application들에서 아주 유용합니다. 예를 들어 native app webview에서 작동할 때 등에서요. jQuery Mobile 프레임워크에서는 페이지 플러그인의 addBackBtn 옵션이 true일 경우 헤더에 자동적으로 back버튼을 추가해 줍니다. 이 기능은 또한 페이지 div 에 data-add-back-btn="true" attribute로 세팅되어져 있으면 적용됩니다.



앵커에 data-rel="back" attribute를 사용하면 앵커에 어느곳을 클릭하던지 back button을 누른 효과가 날 겁니다. history entry의 바로 이전 화면으로 돌아가고 anchor's의 디폴트 href는 무시할 겁니다. 이 기능을 사용할 때 실제로 돌아가는 페이지가 어떤 페이지인지를 알려 줄 수 있는 표시를 해 주세요. href를 걸어달라는 겁니다. 그러면 C-Grade 브라우저를 사용하는 유저에게도 불편함 없이 사용할 수 없도록 할 겁니다.


history 내의 back 화면으로 가는 것이 아니라 reverse transition을 하기를 원하신다면 data-direction="reverse" attribute를 사용하시면 됩니다.


Customizing the back button text


back button text를 configure 하고 싶으시면 페이지 element에 data-back-btn-text="previous" attribute 를 사용하시면 됩니다. 아니면 페이지 플러그인 옵션을 통해서 프로그래밍으로 set 하실 수도 있습니다.


$.mobile.page.prototype.options.backBtnText = "previous";


Default back button style


백 버튼에 role-theme을 설정하고 싶으시면 아래와 같이 하면 됩니다.


$.mobile.page.prototype.options.backBtnTheme = "a";


이 기능을 프로그래밍적으로 하시려면 이 옵션을 mobileinit 이벤트 핸들러에 넣어 주세요.


Custom header configurations


디폴트 세팅이 아닌 헤더를 만들고 싶으면 그냥 콘테이너에 custom styled markup을 씌우시기만 하시면 됩니다. div 같은 걸로요. 플러그인은 헤더 콘테이너 안의 wrapped 콘테이너에 자동 버튼 로직을 적용하지 않을 겁니다. 그러니까 여러분은 여러분 나름대로의 스타일을 넣으실 수 있습니다.


헤더 data-role을 사용하지 않고도 custom bar를 만들 수 있습니다. 예를 들어 ui-bar를 추가해서 스탠다드 바에 apply 하고 ui-bar-b 클래스를 추가해서 여러분의 theme에서 bar swatch styles를 assign 하시면 됩니다.


<div class="ui-bar ui-bar-b">
    <h3>I'm just a div with bar classes and a
       <a href="#" data-role="button">Button</a></h3>
</div>


ui-bar 는 페이지의 full width로 된 헤더나 footer bar에는 추가하지 말아야 합니다. 이렇게 하면 parent container의 full-width element 세팅을 bread out 할 겁니다. full-width 툴바 안에 패딩을 추가하려면 element 안에 툴바의 content를 wrap 하시고 element 대신 padding을 apply 하세요.

하지만 간단하게 style을 적용함으로서 예제 파일의 마지막 바와 같은 메세지 바를 쉽게 만들 수도 있습니다.




반응형

'jQuery Mobile > JQM Tutorial' 카테고리의 다른 글

JQuery Mobile - Fixed toolbar Methods/Events  (0) 2012.07.29
JQuery Mobile - Fixed toolbar options  (0) 2012.07.29
Fixed toolbars  (0) 2012.07.28
JQuery Mobile - Navbar  (2) 2012.07.25
JQuery Mobile - Footers  (0) 2012.07.24
JQuery Mobile - Toolbar types  (0) 2012.07.21
JQuery Mobile - Theming Page  (0) 2012.07.12
JQuery Mobile - touchOverflow 기능  (0) 2012.07.09
JQuery Mobile - PhoneGap apps  (1) 2012.07.09
JQuery Mobile - Scripting pages  (1) 2012.07.05

JQuery Mobile - Toolbar types

2012. 7. 21. 01:58 | Posted by 솔웅


반응형


이제 jQuery Mobile Tutorial 의 Component 부분 Page & dialog 를 끝마치고 두번째 주제인 Toolbars 로 들어갑니다.


생각보다 시간이 많이 걸리네요. 어쨌든 조금씩 조금씩 공부해 나가다 보면 조만근 끝까지 돌파 하겠죠?

오늘은 Toolbars 의 첫 시간입니다.



Toolbar types


jQuery Mobile에는 두가지 표준 툴바 종류가 있습니다. : Headers and Footers.

  • Header bar는 페이지 title로 사용됩니다. 대부분의 경우 각 mobile page내의 첫번째 엘리먼트가 되죠. 특히 페이지 title이 포함되고 또 두 개의 버튼까지 포함할 수 있습니다.
  • Footer bar는 대개 각 모바일 페이지의 마지막 element 입니다. 그리고 그 내용과 기능면에서 header 보다 더 자유로운 경향이 있죠. 여기에는 text와 버튼들의 조합이 들어가게 됩니다.


header나 footer 안에는 대개 horizontal navigation이나 tab bar 가 들어가는 것이 일반적입니다. jQuery Mobile에는 이런 경우 hirizontal button bar 안에 들어가는 링크들의 리스트 보여줄 수 있는 navbar widget 를 제공하고 있습니다.

이 툴바들에 추가 할 수 있는 attribute들을 모두 보려면 data- attribute reference를 참조하세요.



Toolbar positioning options


header와 footer들은 여러 방법으로 페이지에 위치 지워질 수 있습니다. 디폴트로 툴바들은 inline 포지셔닝 모드를 사용합니다. 이 모드에서는 헤더와 푸터들이 일반적인 문서 flow(default HTML behavior)에 맞게 자리 잡습니다. 이 경우는 JavaScript와 CSS 포지셔닝 지원 여부에 관계 없이 모든 device들에서 작동을 합니다. (visible)


"fixed" positioning mode 는 툴바들을 CSS fixed positioning 을 지원하는 브라우저의 viewport 안에 있는 top 이나 bottom에 툴바들을 위치시킵니다. CSS fixed positioning은 대부분의 데스크탑 브라우저와 iOS5+, 안드로이드 2.2+, 블랙베리 6 등에서 지원합니다. 이 기능을 지원하지 않는 브라우저들에서는 이 툴바들은 페이지내의 inline position으로 지정이 될 겁니다.


tap-togglingl이 가능하면 스크린을 tapping 하면 fixed toolbar의 visibility가 toggle 될 겁니다. 툴바가 보이지 않을 때 페이지를 tap하면 보이게 될 겁니다. 다시한번 tap 하면 사라지구요. 이 기능은 유저에게 필요하기 전에는 툴바를 보이지 않음으로서 컨텐츠가 좀 더 넓은 화면에서 표시될 수 있게 해 줍니다. 기억해 두셔야 될 것은 fixed toolbar는 실제로는 hide 된게 아니라는 겁니다. fixed와 static positioning 사이에서 왔다 갔다 하는 겁니다. 이 의미는 만약 여러분이 페이지 top 에 있다면 그 헤더 툴바를 안 보이도록 tap-toggle 할 수 없다는겁니다. 문서의 아주 밑으로 scroll 됐을 경우 fixed footer에도 이러한 경우는 마찬가지로 적용됩니다.


이 기능을 헤더와 풋터에 세팅하려면 data-position="fixed" attribute를 헤더나 풋터 element에 추가하세요.


"fullscreen" position mode는  fixed mode가 아닐 때 문서의 한 지점을 점유툴바가 페이지 콘텐츠를 덮는것을 제외하고는 fixed mode와 같습니다. 이 기능은 컨텐츠가 전체 스크린을 차지하고 툴바는 숨고 스크린을 탭 했을 때만 나타나도록 하는 포토나 비디오 뷰어 같은 immersive app일 경우에 아주 유용할 겁니다. 이 경우의 툴바들은 페이지 콘텐츠의 위에 자리잡을 것입니다. 그러니까 특정 상황에서 유용하게 사용될 수 있고 어떤 상황에서는 그렇지 않을 수도 있습니다.



반응형

'jQuery Mobile > JQM Tutorial' 카테고리의 다른 글

JQuery Mobile - Fixed toolbar options  (0) 2012.07.29
Fixed toolbars  (0) 2012.07.28
JQuery Mobile - Navbar  (2) 2012.07.25
JQuery Mobile - Footers  (0) 2012.07.24
JQuery Mobile - Header structure  (0) 2012.07.23
JQuery Mobile - Theming Page  (0) 2012.07.12
JQuery Mobile - touchOverflow 기능  (0) 2012.07.09
JQuery Mobile - PhoneGap apps  (1) 2012.07.09
JQuery Mobile - Scripting pages  (1) 2012.07.05
JQuery Mobile - Dynamically Injecting Pages  (0) 2012.06.28

JQuery Mobile - Theming Page

2012. 7. 12. 20:57 | Posted by 솔웅


반응형

Page Theming


jQuery Mobile 에서는 페이지의 style을 지원하는 rich theming system을 제공하고 있습니다. 각 페이지 위젯에는 자세한 theming documentation이 있습니다. 이 글에서는 어떻게 theming이 apply 되는지 몇개의 high-level 예제들을 살펴보도록 하겠습니다.


data-them attribute는 헤더나 footer 콘테이너에 apply 될 수 있습니다. 이 콘테이너에 apply 되서 lettered theme color swatch들을 적용할 수 있도록 합니다. data-theme attribute가 content container에 적용 될 때에는 data-role="page"가 적용된 div나 콘테이너에 넣으라고 권장 드립니다. 그렇게 하면 배경색이 전체 페이지에 적용될 수 있습니다. 이 작업이 끝나면 페이지의 모든 위젯들은 그 페이지 콘테이너에 적용된 theme을 상속 받게 됩니다. header와 footer에는 디폴트로 theme "a"가 적용 됩니다. 모든 element에 theme "b" 가 적용되기를 원하신다면 이것을 header나 footer에 적용 시키세요. 페이지 div에 data-theme="b"를 하듯이 header와 footer div에도 이렇게 하면 됩니다. 이 디폴트 theme은 다양한 견본(swatches)들을 활용해서 visual texture를 만들고 각각 에 맞는 최상의 contrast를 다양한 element들에 적용하고 있습니다.




위 화면에 대한 소스와 기타 theme a ~ e 까지의 간단한 예제가 있는 소스를 아래에 올립니다.


themingpages.html


그리고 Tutorial Page에 가시면 A~E 까지의 theme들을 적용한 각 form 들을 보여주는 페이지가 있습니다.


이 페이지들을 따로 작업해서 파일로 만들었습니다.

보시면 도움이 될 겁니다.



themingApage.html


themingBpage.html


themingCpage.html


themingDpage.html


themingEpage.html



소스들을 보시면서 이것 저것 바꾸시고 테스트해 보시면 확실히 자기것으로 만들 수 있을 겁니다.


그럼 항상 즐 코딩 하세요.


반응형

'jQuery Mobile > JQM Tutorial' 카테고리의 다른 글

Fixed toolbars  (0) 2012.07.28
JQuery Mobile - Navbar  (2) 2012.07.25
JQuery Mobile - Footers  (0) 2012.07.24
JQuery Mobile - Header structure  (0) 2012.07.23
JQuery Mobile - Toolbar types  (0) 2012.07.21
JQuery Mobile - touchOverflow 기능  (0) 2012.07.09
JQuery Mobile - PhoneGap apps  (1) 2012.07.09
JQuery Mobile - Scripting pages  (1) 2012.07.05
JQuery Mobile - Dynamically Injecting Pages  (0) 2012.06.28
JQuery Mobile - Ajax, hashes & history 02 -  (0) 2012.06.27


반응형

touchOverflowEnabled: Deprecated in 1.1.0

jQuery Mobile 1.1 이전에서는 true fixed toolbar 지원이 touch에 대해 overflow-scrolling 하는 CSS 프로퍼티로 native browser 지원이 가능했었습니다. 지금은 iOS5에서만 지원되고 있습니다. jQuery Mobile 1.1 버전에서는 이 CSS 프로퍼티를 더 이상 사용하지 않습니다. 우리는 이 프로퍼티를 내부적으로 사용하는 부분을 모두 없앴습니다. 하지만 이미 이 프로퍼티를 사용하고 있는 어플리케이션에 문제가 발생하지 않도록 $.mobile 객체에 글로벌하게 정의해 놓고 있습니다. 이 프로퍼티는 remove 하라고 flag 되어 있습니다. 하지만 아직까지 $.support 를 통해서 남아있고 지금 현재로서는 이것을 완전 remove할 계획을 가지고 있지는 않습니다.


touchOverflow: Improved page transitions and true fixed toolbars


현재 보이는 화면과 앞으로 전환될 화면은 viewport에 나란히 있습니다.  이 화면전환이 아래쪽으로 된다면 이 두 페이지가 화면전환이 시작될 때 같은 viewport에 있어야 합니다. 그리고 손가락을 위쪽으로 해서 scroll을 하겠죠. 그러면 그 다음 화면이 밑에서부터 따라 올라올 겁니다. 만약에 back button을 클릭한다면 scroll up 하고 화면전환을 하고 이전 scroll position을 저장해야 합니다 .아직까지 모바일 브라우저의 속도가 느린편이라 이 스크롤 움직임은 실제 유저의 움직임을 따라가지 못할 수 있습니다.


이러한 문제점을 극복할 방법은 두 페이지를 각각의 콘테이너에 담는것입니다. 각각은 나름대로의 internal scroll bark 를 가지고 있습니다. 이 의미는 document를 더 이상 scroll 할 필요가 없다는 것이죠. 혹은 좀 더 자연스럽게 스크롤 포지션을 저장하는 것이 필요하다는 겁니다. fixed toolbar들을 만들어서 internal scrolling 과 함께 바깥의 콘테이너에  넣음으로서 이를 쉽게 구현할 수 있습니다.


How it works


overflow:auto 의 touch-targeted version을 지원하는 iOS5 를 한번 보죠. 여기에서는 native momentum scrolling과 함께 internal scrolling region을 허용합니다. 우리는 여기에 touchOverflow 라는 기능을 추가했습니다. 이 기능은 이 두개의 true "fixed" toolbar들을 사용할 수 있는 새로운 CSS capability들을 가능하게 합니다. 그로 인해 iOS5에서 아주 부드럽게 화면전환이 일어나도록 만들죠. 모두 웹 표준을 사용하고 있고 약간의 코드를 추가했습니다.


이 기능은 touchOverflowEnabled 라고 부르는데 CSS에서 overflow scrolling을 지원할 미래의 브라우저를 위해 디자인 됐습니다. 이 기능은 최고의 퍼포먼스를 위해 아직 테스트와 디버깅이 필요하기 때문에 디폴트로 off 상태입니다. 조만간 이 기능을 on 으로 활성화 할 수 있기를 바랍니다. 아래에 이 global option을 어떻게 enable 시키는지 예제가 있습니다.


<script>
$(document).bind("mobileinit", function(){
  $.mobile.touchOverflowEnabled = true;
});
</script>



이 기능이 activate 되면 프레임워크는 이 두 overflow를 브라우저가 support 하는지 찾게 됩니다. 그리고 -webkit-overflow-scrolling:touch CSS properties 를 찾게 되죠. 이 두가지를 지원하는 브라우저에서는 native overflow와 함께 dual page container 모델로 switch 합니다. 그래서 각각의 안에서 스크롤링을 하게 되어 true fixed toolbars smooth transition이 일어나도록 하죠. 이렇게 하면 native performance에 아주 가까운 인터페이스 build를 가능하도록 해 줍니다.

이 기능의 demo 를 보시려면 iOS5의 이 페이지를 체크하세요.


A few downsides


새 기능인 경우 완벽할 수는 없습니다. 이 기능을 activating 할 때 몇가지 고려해야 할 사항들이 있습니다.


  • 리스트나 form 같은 child element들은 가끔 iOS5에서 overflow된 페이지내의 embedded 일 때 render를 하지 않는 경우가 있습니다. 아주 random 하게 일어나는 현상이지만 그냥 둘 수는 없는 문제죠. 그래서 우리는 translage-z CSS 프로퍼티를 추가해서 IOS가 content를 render 하도록 force 하고 있습니다. 이 경우의 단점은 transform이 apply 됐을 때 모든 elements들은 relative 로 포지션이 set 되서 여러분의 layout에 어떤 이슈가 발생할 수가 있습니다.
  • -webkit-overflow-scrolling:touch는 status bar 를 tap 했을 때 위에서 아래로 스크롤 하는 이벤트가 제대로 작동하지 않는 것 같습니다. 애플에서 이와 관련해서 개선해주기를 바랍니다. 왜냐하면 이 기능은 아주 필요하거든요.
  • overflow이고 -webkit-overflow-scrolling:touch 프로퍼티가 세팅돼 있을 때 iOS는 그 parent의 (우리의 경우는 page) 어떤 overflow:hidden 프로퍼티도 무시하는 현상이 나타납니다. 그래서 viewport보다 넓은 이미지나 코드 블럭이 있다면 horizontal scrolling 이 나타납니다.
  • 이 기능이 active 일 때 메타 viewport 태그를 사용하게 되면 유저 zoom 이 제대로   작동하지 않게 됩니다. 왜냐하면 툴바와 페이지 콘텐트 모두 이상한 size로 zoom될 수 있고 다시 zoom back out 하는것이 무척 어렵기 때문입니다. 이런 이상한 현상을 완화하기 위해 우리는 fixed toolbar와 overflow container를 사용하는 것이 더 중요하게 됩니다.
  • re-load 된 페이지로 되돌아갈 때 스크롤 포지션을 잃어버릴 수가 있습니다. 만약 DOM caching이 on 상태이면 이런 이슈는 거의 발생하지 않을 겁니다.
  • 이 기능은 아직까지 실험적입니다. 그러니까 이런 이상한 현상들이 모두 해결된 상황은 아닙니다. 주의해서 사용하시고 항상 테스트를 하세요.


Don’t other mobile platforms already support overflow?


예 다른 플랫폼도 overflow를 지원합니다. 안드로이드의 허니컴과 블랙베리의 플레이북도 overflow를 지원합니다. 하지만 저희가 테스트해 본 결과 그 기기들에서의 overflow는 부드럽지 않습니다. 페이지들은 버벅거리거나 스크롤링 동안에 잠깐씩 멈칫멈칫 합니다. 저희들은 이 기계 제조사들에게 이 기능이 개선되어야 한다고 의견을 제시하고 있습니다.


더 중요한 것은 overflow가 정확하게 되어야 하는것입니다. 우리가 그냥 간단하게 페이지의 auto CSS rule에 overflow를 설정해 놓으면 안드로이드나 iOS의 이전 버전이면서 많은 사람들이 사용하는 플랫폼에서는 내용의 나머지 부분이 잘려나갈겁니다. (iOS의 경우에는 이런 경우 two-finger scroll을 할 수 있을 겁니다. 하지만 아무도 모르고 있을 겁니다.) iOS5에서 애플은 CSS 프로퍼티 -webkit-overflow-scrolling:touch 를 추가했습니다. 현명한 조치라고 생각합니다. 이렇게 함으로서 저희들은 이 touch 스크롤링 프로퍼티를 테스트할 수 있었습니다. 그래서 만약 이 기능을 지원한다면 그 브라우저에서는 overflow rule을 추가할 수 있겠죠.


우리는 이 CSS-based 프로퍼티들을 지원해 달라고 디바이스와 브라우저 개발사들에게 요청하고 있습니다. 왜냐하면 이 기능이 rich mobile 웹 앱을 만드는데 아주 중요한 요소가 될 거라고 믿기 때문입니다. 만약에 오페라, 파이어폭스, 마이크로 소프트같은 회사에서 이 기능을 지원하면 우리는 이 touch scrolling property를 위해 vender-prefixed additions를 추가할 것입니다. 사람들이 IOS5에서 얼마나 페이지 전환이나 fixed toolbar들이 더 훌륭하게 진행되는지를 보게 되면 다른 브라우저들에서도 하루빨리 이 기능을 적용할 거라고 기대합니다. JS-based scroller script들은 새로운 CSS capability 들이 지원되지 않는 브라우저에 polyfill로서 존재하고 있는 상황입니다. 우리는 모바일 웹의 잠정적인 개선사항을 다루는 툴을 통해 간단하게 이 기능을 볼 수 있을 뿐입니다.


Debugging touchOverflow


일반적으로 touchOverflow 는 overflow area의 touch-scrolling을 지원하는 디바이스에서만 가능합니다. 데스크탑에서는 가능하지 않습니다. 그래서 이 touchOverflow 기능을 디버깅하는것이 어렵습니다. 이 touchOverflow 를 모둔 브라우저에서 가능하도록 하려면 아래 예제처럼 하세요.


<script>
$(document).bind("mobileinit", function() {
  $.support.touchOverflow = true;
  $.mobile.touchOverflowEnabled = true;
});
</script>



반응형

JQuery Mobile - PhoneGap apps

2012. 7. 9. 22:36 | Posted by 솔웅


반응형

Building PhoneGap apps with jQuery Mobile


폰갭(PhoneGap)은 웹 기술로 된 native application 을 개발할 수 있도록 해 주는 HTML5 app 플랫폼 입니다. 애플리케이션은 일반 HTML 페이지로 빌드 됩니다. 이것을 UIWebView나 WebView 안에 넣은 native 어플리케이션 처럼 작동시키도록 package 되는 겁니다. 폰갭은 jQuery Mobile과 잘 어울려서 많이 사용 되고 있습니다. 폰갭과 함께 사용하는데 몇가지 팁을 제공해 드리려고 합니다.


local file:// URL로 폰갭 어픞피케이션에 의해 initial application document가 로드 됩니다. 이 의미는 여러분 회사의 remote server로부터 받은 페이지를 pull in 하고 싶으시다면 그 서버의 절대 URL 경로를 넣어야 한다는 겁니다. 왜냐하면 여러분의 document는 근본적으로 file://URL 형식이고 여러분의 remote 서버로부터 페이지나 assets들을 로딩하는 것은 특정 상황에서는 block 될 수 있는 cross-domain request 이기 때문입니다.


Phone Gap jQuery Mobile 어플리케이션 안에서 cross-domain 페이지들을 접근하는 것은 두가지 중요한 기능을 controll 해야 가능합니다. $.support.cors$.mobile.allowCrossDomainPages 이 그것입니다. 이것은 추후에 폰갭이 버전업해서 기능 추가나 기능 변경이 있게 되면 영향을 받을 수 있습니다.





$.support.cors


jQuery core에는 $.support.cors boolean 이 있습니다. 이것은 cross-domain request를 위한 W3C의 Cross-Origin Resource Sharing 기능을 지원하는 브라우저인지 아닌지를 나타내는 겁니다.


jQuery Mobile은 jQuery core의 $ajax() functionality에 의존하고 있습니다. $.support.cors 는 $ajax에게 cross-domain 페이지들을 로드하라고 하기 위해 반드시 true로 세팅되어야 합니다. 블랙베리캍은 일부 플랫폼에서는 webviews가 지원되지만 $.ajax()가 cross-domain 을 할 수 없도록 $.support.cors 값이 false로 세팅되어 있는 경우가 있다는 report를 받았습니다. 이럴 경우는 페이지나 asset 들의 로딩이 fail 될 수 있습니다. $.support.cors를 true로 세팅해야 합니다.


$.mobile.buttonMarkup.hoverDelay


만약 버튼 down이나 hover 상태가 (lists,buttons,links etc) 약간 버벅거린다고 느껴지시면 $.mobile.buttonMarkup.hoverDelay 가 사용중일 가능성이 있습니다. 이렇게 되면 터치 이벤트와 관계된 클래스와의 작동 시간을 줄일 수도 있지만 동시에 그 클래스가 유저가 스크롤링할 때도 apply 될 수도 있습니다. (예. 긴 리스트의 링크가 있을 때)


$.mobile.allowCrossDomainPages


jQuery Mobile이 external page를 로드하려고 할 때 이 request는 $.mobile.loadPage()를 통해 run 됩니다. 이것은 $.mobile.allowCrossDomainPages confituration 옵션이 true로 세팅되었을 경우의 cross-domain request에서만 해당 도비니다. 왜냐하면 jQuery Mobile은 그 브라우저의 location hash내의 어떤 페이지가 view 되고 있는지를 track 하기 때문입니다. 그러면 cross-site scripting 공격이 가능할 수 있습니다. 질문 안의 XSS 코드가 hash를 조종할 수 있고 그 결과로 cross-domain URL을 세팅할 수 있기 때문입니다. 이것이 $.mobile.allowCrossDomainPages 의 디폴트 값을 false로 하는 주요 이유입니다.


그래서 폰갭 앱 에서는 원격 서버의 assets 로딩을 하게 되는 phone home 일 경우 이 $.support.cors$.mobile.allowCrossDomainPages 반드시 true로 세팅되어 있어야 합니다. $.mobile.allowCrossDomainPages 옵션은 이런 cross-domain request 가 일어나기 전에 세팅되어 있어야 합니다. 그래서 저희는 이것을 mobileinit 핸들러에 wrapping 할 것을 권장합니다.


$( document ).bind( "mobileinit", function() {
    // Make your jQuery Mobile framework configuration changes here!

    $.mobile.allowCrossDomainPages = true;
});


PhoneGap White Listing


PhoneGap 1.0은 폰갭의 internal webview가  cross-domain request를 가능하게 하는 white-listing server에 대한 아이디어를 소개했습니다. 여기에 대한 정보는 PhoneGap wiki에서 보실 수 있습니다.


모든 플랫폼에서 이 white-listing feature 를 지원하는 것은 아닙니다. 그러니까 보다 자세한 사항은 PhoneGap 문서를 확인하세요. 폰갭 1.0 이전 버전은 어떤 서버에든 cross-domain request를 허용합니다.


Still having issues?


Here are a few more tips that aren't specifically related to PhoneGap but are good to know:

아래는 직접적으로 폰갭과 관련이 있지는 않지만 알아 두시면 도움이 될 사항들입니다.


앱을 인스톨 할 때 pushState feature 를 disabling하도록 추천합니다. 왜냐하면 이 기능이 있으면 원하지 않은 곳으로 navigation 하는 행위가 일어날 수 있기 때문입니다. webview 안에 URL이 보일 필요가 없다면 이 이 기능을 계속 able 상태로 놓아 둘 필요가 없습니다.


안드로이드에서는 웹뷰에서 loading 하는 시간이 길면 강제로 timeout 하게 합니다. 그런데 그 시간이 여러분이 필요로하는 시간보다 더 짧을 수 있습니다. 이 경우 이클립스 플러그인에서 Java class 가 generated 될 때 수정해서 timeout을 바꿀 수 있습니다.


super.setIntegerProperty("loadUrlTimeoutValue", 60000);



반응형

JQuery Mobile - Scripting pages

2012. 7. 5. 00:22 | Posted by 솔웅


반응형

Scripting pages in jQuery Mobile


jQuery Mobile은 Ajax-powered navigation system을 사용하고 있어서 여러분의 content를 다루는 script를 write 할 때 알아두면 좋을 몇가지가 있습니다. 좀 더 자세한 사항은  global configuration options, events, and methods 같은 mobile API를 읽어보시던가 Ajax navigation model의 technical detail 부분을 파 보시면 도움이 될 겁니다.


Scripts & styles in the head


jQuery Mobile-driven site에서 유저가 클릭할 때 navigation system의 디폴트 behavior는 Ajax request를 formulate 하기 위해 링크의 href를 사용하는 것입니다. (request의 디폴트 link behavior인 requesting에 대한 full page load 하는 href 를 다루는 것을 하는 대신에..). 그 Ajax request가 완료되고 나면 프레임워크는 전체 text content를 받을 겁니다. 하지만 그것은 response 의 body element content 만 inject 할 겁니다. (혹은 특별한 경우 data-role="page"가 제공될 경우 그 엘리먼트를 inject 할 겁니다). 그런데 페이지의 head에는 별 특별한것이 없기 때문에 사용될게 없습니다. (페이지 타이틀 같은게 있기는 하지만 페이지에 표시할 별 다른 특별한 것은 없습니다.)  스크립트는 이런 상황에서 다이나믹하게 로드 됩니다. 이 스크립트가 일반 http request를 통해 로드된다면 로드되는 순서가 항상 같다는 보장은 없습니다. 


이 의미는 페이지의 헤드부분에 있는 어떤 스크립트나 스타일이라도 ajax를 통해서 로드되는 페이지일 때 어떤 effect도 없을거라는 겁니다. 다만 http를 통해 일반적으로 request될 때 excute 될 겁니다. jQuery Mobile 싸이트의 스크립트인 경우는 두 경우 모두를 고려해야 합니다. Ajax를 통해서 request 될 경우 head 부분이 무시될거라는 것은 이런 자바스크립트가 다시 excute 될 가능성이 아주 높다는 겁니다. (같은 스크립트를 모든 페이지에서 참조하는게 일반적인 구조이기 때문이죠.) 이것 때문에 작업하는데 좀 복잡한 점이 있기 때문에 우리는 page-specific script는 개발자에게 excuting 하는 작업을 미루고 있습니다. 그리고 head script는 브라우저 세션별로 딱 한번 execute 될 거라고 가정한 상황에서 작업을 합니다.


jQuery Mobile 싸이트로 만들 때 가장 손 쉬운 접근법은 모든 페이지의 head 부분에서 같은 스타일쉬트와 스크립트 셋트를 참조하는 것입니다. 특정 페이지에서는 특정 스크립트나 특정 스타일 쉬트를 로드해야 한다면 pageInit 이벤트에 로직을 binding 하는 방법(자세한 것은 아래에 있습니다.)을 추천합니다.  이렇게 하면 특정 페이지가 생성될 때 필요한 코드를 run할 수 있습니다. (id attribute나 다른 방법으로 determined 될수 있습니다.) 아래있는 예제는 페이지가 직접 로드되던가 Ajax를 통해 보여지고 pull in 되는 경우 code가 execute될 겁니다.


해당 페이지에만 적용되는 스크립트를 구현하기 위한 다른 접근법은 아무런 data-role=page 엘리먼트가 정의되지 않은 bodey element 의 끝에 script를 include 시키는 방법이 있을 겁니다. 만약 이 방법으로 여러분의 스크립트를 include 시킨다면 이 스크립트는 Ajax나 일반 HTTP를 통해 페이지가 로드될 때 execute 될 겁니다. 그래서 이 스크립트가 매 페이지마다 있으면 문제가 일어날 수도 있습니다. 오직 그 페이지에만 unique한 스크립트는 Ajax를 통해 fetch되는 페이지일 때 실행하도록 그 element 안에 위치시킬 수 있습니다.


pageinit = DOM ready


$(document).ready() 함수를 이용해서 DOM이 준비 되자마자 DOM-specific code를 execute 시키기는 것이 jQuery를 사용하려는 사람들이 처음 배우는 것입니다. jQuery Mobile 사이트와 앱 그리고 페이지들은 유저가 navigate 하는 것과 같은 DOM으로 request 되고 inject 됩니다. 그래서 DOM ready 이벤트를 단지 첫번째 페이지를 execute 하기위해 사용하는 것은 그다지 유용하지는 않습니다. jQuery Mobile에서 새로운 페이지가 로드되고 생성될 때마다 코드를 실행시키기위해 여러분은 pageinit 이벤트에 bind 해 주시면 됩니다.

이 pageinit 이벤트는 그것이 initialized 될 때 페이지에 trigger 됩니다. initialization 된 바로 직후에 실행되죠. 대부분의 jQuery Mobile의 공식 위벳들은 이 이벤트에 근거해서 자동적으로 initialize 됩니다. 여러분의 코드에 대해서도 같은 방식으로 적용하시면 됩니다. 


$( document ).delegate("#aboutPage", "pageinit", function() {
  alert('A page with an ID of "aboutPage" was just created by jQuery Mobile!');
}); 


만약 pageinit 이벤트가 fire 되고 위젯들이 auto-initialized 되기 전에 페이지의 content들을 다루고 싶다면 pagebeforecreate 이벤트를 바인드 하시면 됩니다.


$( document ).delegate("#aboutPage", "pagebeforecreate", function() {
alert('A page with an ID of "aboutPage" is about to be created by jQuery Mobile!'); });


Important note: pageCreate() vs pageInit()


이전의 Beta2 버전에서는 jQuery Mobile의 페이지와 child widget markup을 다루는 방법으로 권장됐던 것이 pagecreate 이벤트를 바인드 하는 것이었습니다. Beta2에서 internal change는 위벳 메소드에 direct call 하는 장소에 pagecreate를 bind 함으로서 각각의 위젯들을 decouple 하도록 만든 것이었습니다. 결과적으로 mobileinit에서 pagecreate로 유저가 바인딩하는 것은 각각의 플러그인에 의해서 enhance 돼있는 markup 이전에 바인딩을 실생시키게 됩니다. jQuery UI 위젯 Factory의 lifecycle을 유지하기위해 initialization 메소드는 create 메소드 이후에 invoke 됩니다. 그래서 pageinit 이벤트는 DOM과 자바스크립트 객체들의 post enhancement manipulation에대해 적절한 타이밍을 제공하게 되는 겁니다.  간단히 말하면 이전에 여러분이 페이지가 보여지기 이전에 enhanced markup을 다루기위해 pagecreate를 사용했다면 지금 버전에서는 대신 pageinit을 사용하면 된다는 얘기입니다.


Changing pages


현재의 active page를 바꾸기를 원하신다면 여러분은 changePage 메소드를 사용하시면 됩니다. 페이지를 바꾸기위한 방법에는 아주 많은 메소드와 프로퍼티들이 있을 수 있습니다. 그중 두가지 예제를 아래에서 다루겠습니다.


//transition to the "about us" page with a slideup transition
$.mobile.changePage( "about/us.html", { transition: "slideup"} );

//transition to the "search results" page, using data 
//from a form with an ID of "search""
$.mobile.changePage( "searchresults.php", { type: "post", data: $("form#search").serialize() });


Loading pages

외부 페이지와 그 콘텐츠 enhance를 로드하기위해 그리고 그럿을 DOM에 넣기 위해 loadPage method를 사용합니다. 페이지를 로딩할 때 여러분이 세팅할 수 있는 메소드와 프로퍼티들은 무수히 많지만 아래 간단한 한가지 예제만 보여 드리겠습니다.


//load the "about us" page into the DOM
$.mobile.loadPage( "about/us.html" );


Enhancing new markup


페이지 플로그인은 pageInit 이벤트를 dispatch 합니다. 대부분의 위젯들은 auto-initialize 하기위해 이것을 이용하죠. 위젯 플러그인 스크립트가 참조 되면 그 페이지에서 찾은 위젯들의 instance를 자동적으로 enhance 하게 됩니다.


만약 여러분이 클라이언트 사이드에서 새로운 markup을 generate 시킨다던가 Ajax를 통해서 콘텐트를 로드한다던가 그 콘텐트를 페이지에 inject 하려고 한다면 create 이벤트를 trigger 하시면 됩니다. 그러면 새로운 markup안에 있는 모든 플러그인들에 대한 auto-initialization을 처리할 수 있습니다. 이것은 어떤 엘리먼트에서도 trigger 될 수 있습니다. (page의 div에서도 가능합니다.) 그렇게 하면 매뉴얼로 각각의 플러그인(listview 버튼, select 등)을 initializing 하는 번거로움을 덜 수가 있습니다.



예를 들어 HTML markup 블럭이 Ajax를 통해서 로드됐다면 enhanced version으로 모든 위젯들을 (login form 이라면 inputs and buttons ) 자동적으로 transform 하기 위해 create 이벤트를 트리거 합니다. 예제는 아래에 있습니다.


$(...new markup that contains widgets...).appendTo(".ui-page").trigger("create");


Create vs. refresh: An important distinction


같은 위젯이 가지고 있는 create 이벤트와 refresh 메소드는 서로 다른 중요한 부분이 있습니다. create 이벤트는 한개 이상의 위젯을 가지고 있는 raw markup에 대한 enhancing에 알맞습니다. 반면에 refresh 메소드는 프로그래밍적으로 처리되고 있고 해당 UI로 update될 필요성이 있는 이미 존재하고 enhance된 위젯을 사용하기 위해 필요합니다.


예를 들어 여러분이 페이지 생성 이후에 data-role=listview 어트리뷰트로 정렬돼 있지 않은 새로운 list를 다이나믹하게 추가해야하는 페이지가 있다면 그 리스트의 parent element에 create를 트리거 함으로서 listview 스타일 위젯으로 그것을 transform 하도록 만들겁니다. 그 다음에 좀 더 많은 아이템들이 프로그램적으로 추가된다면 listview의 refresh 메소드를 부름으로서 enhanced state로 그 새로운 리스트 아이템들을 업데이트하게 되고 이미 존재하는 리스트 아이템들을 untouched로 남아있게 됩니다.


Scrolling to a position within a page


Back button behavior를 유지하기 위해 URL hash를 사용하고 난 후 그 페이지의 어떤 포지션으로 jump down 하기 위해 anchor를 사용하는것은 일반적인 anchor link(#foo)를 사용해서 할 수 없습니다. 스크롤 이벤트 리스너를 trigger 하지 않고 특정 Y 포지션으로 스크롤하기 위해 silentScroll 메소드를 사용해야 합니다. Y 위치로 yPos 인자를 pass 합니다. 아래 예제가 있습니다.


//scroll to Y 300px
$.mobile.silentScroll(300);


Binding to mouse and touch events


모바일에서 또 한가지 중요하게 생각해야 할 것은 마우스와 터치 이벤트를 처리하는 것입니다. 이 이벤트들은 모바일 플랫폼에 따라 많은 차이가 있습니다. 그 중에서도 일반적이고 공통적인것은 click 이벤트가 있다는 겁니다. 대개 500~700ms 의 지연이 있게 되죠. 이 지연은 더블 탭이나 스크롤 혹은 extended hold tap 이벤트가 일어나는지 아닌지를 브라우저가 catch 할 수 있는시간입니다. 이 지연을 피하려면 터치이벤트로 바인드 할 수가 있습니다.(ex. touchstart). 하지만 이 접근법에서 주의해야 할 점은 어떤 모바일 플랫폼에서는 (WP7, Blackberry) touch를 지원하지 않는다는 것입니다. 이 이슈를 해결하기 위해 어떤 플랫폼들은 touch와 mouse 이벤트를 동시에 일으킵니다. 그래서 이 두개 타입을 바인드 한다면 하나의 동작에 duplicate event가 발생할 겁니다. 우리의 해결법은 일반화된 마우스와 터치이벤트인 virtual events 세팅을 생성하는 것입니다.



이렇게 하면 기본적인 마우스 이벤트에 대한 리스너를 register 할 수 있도록 해 줍니다. 예를 들어 mousedown, mousemove, mouseup, click 같은 거죠. 이 플러그인은 해당 디바이스에 맞는 가능한 가장 빠른 시간에 listener가 invoke 되도록 화면 뒤에서 적절한 리스너를 register 하도록 해 줍니다. 하지만 아직까지 일반적인 마우스 이벤트에서 일어나는 이벤트들의 순서 부분이 남아있습니다. 각각 다른 이벤트들에 대해 같은 엘리먼트가 register 되도록 multiple handler가 필요하게 되는 것이죠. virtual mouse system은 jQuery bind event에 대한 다음과 같은 virtual evnet들을 발생 시킵니다. vmouseover, vmousedown, vmousemove, vmouseup, vclick, and vmousecancel.


Passing parameters between pages


jQuery Mobile은 internal/embeded 페이지로 pass 하는 query parameter를 지원하지 않습니다. 예를 들어 프레임워크가 #somePage?someId=1로 된 링크를 보면 이것을 "#somePage" 로 해석하고 somPage의 ID로 페이지 div를 navigate 학 ㅔ됩니다. 다음에 #somePage?someId=1의 data-url을 페이지 컨테이너에 적용하게 됩니다. #somePage?someId=2 같은 다른 params에 대한 이차적인 call들은 같은 div에서 찾을 겁니다. 왜냐하면 jQuery Mobile은 이미 세팅된 div의 data-url을 참조할 것이기 때문입니다.  페이지들 사이에서 query parameter가 필요하다면 이를 지원하는 두가지 plugin 이 있습니다. backbone.js나 spine.js를 사용할 수 있도록 하는 가벼운 플러그인으로는  page params plugin가 있고 좀 더 다양한 기능들이 제공 되는 플러그인으로는 jQuery Mobile router plugin 이 있습니다.


반응형


반응형

jQuery Mobile and Dynamic Page Generation


jQuery Mobile은 default click hijacking behavior나 매뉴얼로 $.mobile.changePage()를 call 하는 것을 통해 다이나믹하게 DOM으로 page이 당겨져 올 수 있도록 해 줍니다. 이것은 서버사이드에서 HTML pages/fragments 를 generate 하는데 아주 좋습니다. 하지만 가끔 JSON이나 다른 포맷으로부터 클라이언트 사이드에서 page content를 다이나믹하게 generate 할 필요가 있습니다. 아마도 네트워크 광역폭이나 퍼포먼스적인 이유로 그런 일이 필요할 겁니다. 혹은 서버와 서로 소통하기 위해 서버가 선택할 데이터 포맷일 수도 있겠죠.


클라이언트 사이드에서 page markup을 generate 할 필요가 있는 어플리케이션을 위해 $.mobile.changePage() call 하는 동안 트리거되는 notification에 대해 이해하고 있는것이 중요합니다. 왜냐하면 해당 시간에 여러분의 content를 generate 할 수 있도록  navigation system 에 hook 하는것을 가능하게 해 주기 때문입니다. changePage()를 call 하게 되면 대개 아래와 같은 event notification이 trigger 됩니다.


  • pagebeforechange
    • Fired off before any page loading or transition.
    • NOTE: This event was formerly known as "beforechangepage".
  • pagechange
    • Fired off after all page loading and transitions.
    • NOTE: this event was formerly known as "changepage".
  • pagechangefailed
    • Fired off if an error has occurred while attempting to dynamically load a new page.


이런 notification들은 페이지의 parent container element(

$.mobile.pageContainer)에서 trigger 됩니다. 그리고 document element와 window에까지 계속 떠 다니게 될 겁니다. JSON이나 in-memory JS object 같은 non HTML data를 이용해서 어플리케이션에 page를 inject 하기를 원한다던가 아니면 빠르게 현재 존재하는 페이지의 내용을 modify 하기를 원한다면 pagebeforechange event 가 아주 유용할 겁니다. pagebeforechange event는 URL이나 page element들을 analyzing 하기위해 hook 할 수 있도록 해 줍니다.  어플리케이션은 load 하거나 switch 할거냐고 질문을 받게 되고 pagebeforechange event에서 preventDefault()를 call 함으로서 default changePage() behavior가 short-circuit 할지에 대해서도 질문을 받게 됩니다.




이 기술을 이용하기 위해 working sample을 한번 살펴 보시기 바랍니다. 이 샘플에서는 유저가 navigate 할 수 있는 카테고리 리스트로 메인페이지가 시작합니다. 각 카테고리의 실제 아이템들은 메모리의 javaScript object에 저장되어 있습니다. 이 데이터들은 어떤 곳에서든지 올 수가 있습니다.


var categoryData = {
	animals: {
	  name: "Animals",
	  description: "All your favorites from aardvarks to zebras.",
		items: [
			{
				name: "Pets"
			},
			{
				name: "Farm Animals"
			},
			{
				name: "Wild Animals"
			}
		]
	},
	colors: {
		name: "Colors",
		description: "Fresh colors from the magic rainbow.",
		items: [
			{
				name: "Blue"
			},
			{
				name: "Green"
			},
			{
				name: "Orange"
			},
			{
				name: "Purple"
			},
			{
				name: "Red"
			},
			{
				name: "Yellow"
			},
			{
				name: "Violet"
			}
		]
	},
	vehicles: {
		name: "Vehicles",
		description: "Everything from cars to planes.",
		items: [
			{
				name: "Cars"
			},
			{
				name: "Planes"
			},
			{
				name: "Construction"
			}
		]
	}
};


이 어플리케이션은 어플리케이션에게 어떤 카테고리 아이템이 display 되어야 하는지를 말해주는 hash를 포함한 url이 있는 링크를 사용합니다.



 <h2>Select a Category Below:</h2>
 <ul data-role="listview" data-inset="true">
    <li><a href="#category-items?category=animals">Animals</a></li>
    <li><a href="#category-items?category=colors">Colors</a></li>
    <li><a href="#category-items?category=vehicles">Vehicles</a></li>
 </ul>


내부적으로 이 링크 중 하나를 클릭하면 어플리케이션은 internal $.mobile.changePage() call을 intercept 합니다. 이 $.mobile.changePage() 는 프레임워크의 default link hijacking behavior에 의해 invoke 된 것이죠. 그러면 이제 로드되기 위해 페이지에 대한 URL을 analyze 하게 됩니다. 그리고 나서 이것이 로딩 자체만을 위한 것인지 아니면 일반적인 changePage() 코드로 처리해야 될 것인지에 대해 판단하게 되죠.

어플리케이션은 도큐먼트 레벨에서 pagebeforechange event로 binding 됨으로서 changePage() 로 그 자체를 insert 할 수 있게 됩니다.



// Listen for any attempts to call changePage().
$(document).bind( "pagebeforechange", function( e, data ) {

// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
	if ( typeof data.toPage === "string" ) {

// We are being asked to load a page by URL, but we only
// want to handle URLs that request the data for a specific
// category.
		var u = $.mobile.path.parseUrl( data.toPage ),
			re = /^#category-item/;

		if ( u.hash.search(re) !== -1 ) {

// We're being asked to display the items for a specific category.
// Call our internal method that builds the content for the category
// on the fly based on our in-memory category data structure.
			showCategory( u, data.options );

// Make sure to tell changePage() we've handled this call so it doesn't
// have to do anything.
			e.preventDefault();
		}
	}
});



왜 도큐먼트 레벨에서 listen할까요? 간단히 말하면 deep-linking 때문입니다. 우리는 jQuery Mobile 프레임워크가 initialize 하기전에 active 되기위해 binding이 필요합니다. 그리고 어플리케이션을 invoke 한 initial URL을 어떻게 process 할지 결정하게 됩니다. pagebeforechange binding에 대한 callback이 invoke 됐을 때 callback에 대한 두번째 argument는 initial $.mobile.changePage() call에 pass 될 argument들을 포함한 data object가 될 겁니다. 이 object의 프로퍼티들은 아래와 같습니다.
  • toPage
    • transition 될 페이지를 포함한  jQuery collection object가 될 수도 있고 로드되거나 transition 될 페이지에 대한 URL reference가 될 수 있습니다.
  • options
    • $.mobile.changePage() function 함수의 caller에 의해 pass 된 옵션들을 포함한 Object
    • 옵션의 리스트는 여기에서 찾아 보실 수 있습니다.
우리의 샘플 어플리케이션에서는 URL들이 initial 하게 pass 된 changePage() calls 에 대해서만 관심이 있습니다. 그래서 우리의 callback이 하는 첫번째 일은 toPage의 type을 체크하는 겁니다 그 다음으로는 어떤 URL parsing 유틸리티의 도움을 받아서 우리가 스스로 handling 하기위해 관심을 가지고 있는 hash를 포함한 URL인가에 대해 체크를 합니다. 만약 그렇다면 showCategory()라는 어플리케이션 함수를 call 합니다. 이 함수는 URL hash에 의해 명시된 카테고리에 대한 content를 다이나믹하게 create 할 겁니다. 그리고 이벤트에서 preventDefault()를 call 할 겁니다. pagebeforechange event에서 preventDefault()를 call 하는 것은 다른 작업 없이 exit 하기 위해 $.mobile.changePage() call 을 유발하게 됩니다. 이 이벤트에서 preventDefault() method를 call 하는 것은 changePage() request를 여러분 스스로 핸들링하게되는 jQuery Mobile과 같다고 말할 수 있습니다.


preventDefault()가 call 되지 않는다면 changePage()는 평상시에 하던대로의 작업을 계속 이어나갈 겁니다. 우리의 callback에 pass 된 data object에 대해 짚고 넘어갈 부분은 여러분이 toPage 프로퍼티나 options 프로퍼티에 어떤 change를 했던지 간에 preventDefault()가 call 되지 않으면 changePage() processing에 영향을 줄 것이라는 겁니다. 예를 들어 다른 internal/external 페이지에 특정 URL을 redirect하거나 map 하고 싶다면 우리의 callback은 그 URL이나 redirect 될 페이지의 DOM 엘리먼트로 callback에 data.toPage 프로퍼티를 set 해야 합니다. 마찬가지로 우리는 우리 callback 안의 어떤 옵션에 대한 set이나 un-set을 할 수 있습니다. 그러면 changePage()는 새로운 세팅을 사용하게 될 겁니다.


이제 우리는 어떻게 changePage() call을 intercept 하는지 알게 됐습니다 이제 이 샘플 소스가 그 페이지에 대한 markup을 실제로 어떻게 generate 하는지 자세히 살펴 보겠습니다. 우리의 샘플 소스는 각 카테고리를 display 하기 위해 같은 페이지를 사용하거나 재 사용합니다. 우리의 special link 가 클릭 될 때마다 showCategory()가 invoke 됩니다.


// Load the data for a specific category, based on
// the URL passed in. Generate markup for the items in the
// category, inject it into an embedded page, and then make
// that page the current active page.
function showCategory( urlObj, options )
{
	var categoryName = urlObj.hash.replace( /.*category=/, "" ),

// Get the object that represents the category we
// are interested in. Note, that at this point we could
// instead fire off an ajax request to fetch the data, but
// for the purposes of this sample, it's already in memory.
		category = categoryData[ categoryName ],

// The pages we use to display our content are already in
// the DOM. The id of the page we are going to write our
// content into is specified in the hash before the '?'.
		pageSelector = urlObj.hash.replace( /\?.*$/, "" );

	if ( category ) {
// Get the page we are going to dump our content into.
		var $page = $( pageSelector ),

// Get the header for the page.
		$header = $page.children( ":jqmData(role=header)" ),

// Get the content area element for the page.
		$content = $page.children( ":jqmData(role=content)" ),

// The markup we are going to inject into the content
// area of the page.
		markup = "<p>" + category.description + 
"</p><ul data-role='listview' data-inset='true'>", // The array of items for this category. cItems = category.items, // The number of items in the category. numItems = cItems.length; // Generate a list item for each item in the category // and add it to our markup. for ( var i = 0; i < numItems; i++ ) { markup += "<li>" + cItems[i].name + "</li>"; } markup += "</ul>"; // Find the h1 element in our header and inject the name of // the category into it. $header.find( "h1" ).html( category.name ); // Inject the category items markup into the content element. $content.html( markup ); // Pages are lazily enhanced. We call page() on the page // element to make sure it is always enhanced before we // attempt to enhance the listview markup we just injected. // Subsequent calls to page() are ignored since a page/widget // can only be enhanced once. $page.page(); // Enhance the listview we just injected. $content.find( ":jqmData(role=listview)" ).listview(); // We don't want the data-url of the page we just modified // to be the url that shows up in the browser's location field, // so set the dataUrl option to the URL for the category // we just loaded. options.dataUrl = urlObj.href; // Now call changePage() and tell it to switch to // the page we just modified. $.mobile.changePage( $page, options ); } }


위 샘플에는 우리가 handle 하는 URL의 해쉬는 아래 두가지 부분을 포함하고 있습니다.


#category-items?category=vehicles

? 전에 있는 첫번째 부분은 content를 write할 page의 id입니다.  ? 다음 부분은 어떤 데이터가 사용되고 언제  페이지에 대한 markup을 generate 할지에 대해 알 수 있는 정보 입니다. showCategory()가 하는 첫번째 일은 이 content 를 write 할 페이지의 id를 추출하기 위해 hash를 deconstruct(해채) 하는 겁니다. 그리고 카테고리 이름은 우리의  in-memory JavaScript category object로부터 올바른 data 세트를 찾아올 때 사용됩니다. 어떤 카테고리 데이터를 사용할 지에 대한 작업이 끝난 이후 그 카테고리에 대한 markup을 generate 합니다. 그리고 그것을 그 페이지의 header와 content 부분에 inject 합니다. 그 element에 이전에 있었던 markup들은 모두 씻겨 나갑니다.


이 markup을 inject 한 이후에 막 inject 된 markup list를 잘 사용하기 위해 적당한 jQuery Mobile widget을 call 하게 됩니다. 이 과정은 styled listview에 list markup이 적용되는 일반적인 과정입니다.


이 작업이 일단 끝나면 $.mobile.changePage()를 call 합니다. 그리고 우리가 방금 modify 한 페이지의 DOM 엘리먼트를 pass 합니다. 이 페이지가 보여지기를 원한다고 프레임워크에게 말하기 위해서죠. 이제 이 부분에서 흥미로운 부분은 jQuery Mobile은 보여지는 페이지와 연관된 URL과 함께 브라우저의 location hash를 update 한다는 겁니다. 이러한 일이 일어 날 수 있는 이유는 우리가 각 카테고리에 대해 같은 페이지를 재사용했기 때문입니다. 이것은 이상적인 상황만은 아닙니다. 왜냐하면 그 페이지에 대한 URL은 그것과 관련된 특정 category 정보를 가지고 있지 않기 때문입니다. 이 문제를 해결하기 위해서는 showCategory()가 changePage()에 pass 한 options object에 대한 dataUrl 프로퍼티를 세팅해 주는 일입니다. 우리의 오리지날 URL 대신에 이것을 display 해 달라고 얘기하기 위해서죠.


여기까지가 샘플입니다. 이 샘플이 아주 좋은 예제는 아닙니다. 특히 grade가 낮아서 JavaScript가 turn off 됐을 때에는요. 이 의미는 C-Grade 브라우저에서는 제대로 작동하지 않을 거라는 겁니다. 이렇게 낮은 grade의 브라우저에서 어떻게 제대로 동작할 수 있도록 하는지에 대해서는 나중에 글을 올릴겁니다. 업데이트 된 내용을 보시려면 여기를 참조하세요.



반응형


반응형

Data-url storage


navigation model은 모든 data-role="page" elements에서 data-url attribute를 maintain합니다. 이 data-url attribute는 page element의 근원을 track 하는데 사용됩니다. main application document에 embeded 된 페이지들은 모두 그들의 data-url 파라미터를 가지고 있습니다. 이것은 data-role="page"와 함께 그들의 ID로 세트 됩니다. 유일한 예외상황은 document의 첫번째 페이지에만 해당 됩니다 첫번째 페이지는 특별합니다. 왜냐하면 이 첫번째 페이지는 아이디를 가지고 있다면그 id로 addressed 되거나 document나 base URL (hash fragment가 없이)로 addressed 됩니다.

외부로 가는 페이지들은 ajax를 통해서 다이나믹하게 pull 됩니다. 그리고 그 data-url은 외부페이지와 연관된 경로로 세팅됩니다. 다른 도메인의 외부 페이지 로딩이 가능한 환경이라면 data-url은 absolute URL로 세팅 됩니다.



Auto-generated pages and sub-hash urls


어떤 플러그인들은 페이지 콘텐츠의 일부분을 deep link로 접근할 수 있는 별도의 navigable 페이지로 다이나믹하게 choose 하기도 합니다. 예를 들어 Listview 플러그인을 들 수 있습니다. 그것은 내부에 있는 UL (혹은 OL) 을 별도의 페이지로 분화합니다. 이것은 각각 data-url attribute 가 주어지게 되죠. 그래서 그것은 jQuery Mobile에서 다른 일반적인 페이지들처럼 링크가 걸릴 수 있습니다. 어쨌든 이 페이지들에 링크를 걸기 위해서는 첫번째로 서버로부터 request 되어야 합니다. 이렇게 하기 위해서 플러그인에 의해 자동 generate 되는 페이지들은 다음과 같은 특별한 data-url structure를 사용합니다.


<div data-url="page.html&subpageidentifier">


예를 들어 listview에 의해 generate 된 페이지는 다음과 같은 data-url을 가지게 될 겁니다.


 data-url="artists.html&ui-page=listview-1"


페이지가 request 되면은 jQuery Mobile은 ui-page에서 URL을 split 해야 된다는 것을 압니다. 그리고 그 key 전에 URL의 부분을 HTTP request 합니다. 위에 언급한 listview 예제의 경우 URL은 다음과 같을 겁니다. http://example.com/artists.html&ui-page=listview-1 ...

그리고 jQuery Mobile은 artists.html을 request 할 겁니다. 그 artists.html은 sub page들을 generate 하겠죠. data-url="artists.html&ui-page=listview-1" 와 함께 div도 생성할 겁니다. 그리고 나서 active page로 display 할 겁니다.

전체 URL path를  포함한 element의  data-url attribute 는 단지 &ui-page= 이후에 붙는 부분이라는 의미만이 아닙니다. 이로서 jQuery Mobile은  page data-url attributes와 매치되는 URL의 single consistent mechanism을 유지하게 되는 겁니다.


Cases when Ajax navigation will not be used


특정 상황에서 일반적인 http requests가 Ajax request 대신 사용될 겁니다. 이 경우는 external 웹사이트로 링크를 거는 경우에 해당 됩니다. 여러분은 다음과 같은 link attribute들을 통해 일반적인  http request를 사용하실 수 있습니다.

  • rel=external

  • target (with any value, such as "_blank")



Form submissions


Form submission도 navigation model을 통해서 자동적으로 처리 됩니다. 좀 더 자세한 정보는 forms section 를 참조하세요.


Using the Application Cache


jQuery Mobile에서 application cache를 사용할 때 고려해야할 사항이 있습니다. 어떤 브라우저에서는 cache에 request를 만들 때 성공하면 http status가 0를 report 할 겁니다. 이것은 에러 핸들러를 trigger하기 위해 jQuery Core의 $.ajax를 유발합니다. 이것을 해결하는 방법은 jQuery ajax pre-filter를 사용하는 겁니다. 아래와 같은 방식이 될 겁니다.(credit to jammus for the snippet):


$.ajaxPrefilter( function(options, originalOptions, jqXHR) {
  if ( applicationCache &&
       applicationCache.status != applicationCache.UNCACHED &&
       applicationCache.status != applicationCache.OBSOLETE ) {
       // the important bit
       options.isLocal = true;
  }
});



isLocal을 true로 해서 ajax request가 return 값이 0인 경우 다르게 처리하도록 jQuery Core에 alert 하게 합니다. Local request들은 비슷한 현상이 일어날 겁니다. (예: 0 status) 그리고 Core는 xhr responseText attribute의 content 에 근거해서 성공여부를 결정하기 위해 fall back 할 겁니다.


위와 관련해 한가지 알아두셔야할 점은  manifest 던지 아니던지 가리지 않고 ajax를 통해 만들어진 모든 request들에 대해 isLocal을 true로 세팅할 거라는 겁니다. 그렇게해서 cache가 valid 되는 겁니다. Core가 uncached result에 영향을 주지 않도록 status가 0 일 때 isLocal 값을 컨트롤하기 때문에 지금은 이렇게 작동을 합니다. 하지만 앞으로도 isLocal 이 0 status 값을 처리하기 위한 목적으로만 사용될 지는 보장할 수 없습니다. 만약 그 부분이 바뀌면 여러분의 어플리케이션은 문제를 일으킬 수 있습니다.



Known limitations


jQuery Mobile's page navigation model에 의해 생성된 non-standard environment는 페이지를 만들 때 주의해야 할 아래와 같은 상황들이 있습니다.


  • filename url 없이 디렉토리에 링크를 걸 때 (예를 들어 href="typesofcats/index.html 라고 하지 않고  href="typesofcats/라고 했을 때 ) 여러분은 반드시 trailing slash를 제공하셔야 합니다. 왜냐하면 jQuery Mobile은 url의 / 이후의 글자를 파일이름으로 생각하기 때문입니다. 그렇게 되면 / 이후의 부분은 나중에 참조할 때 사라지게 됩니다.

  • Ajax에 의해 로드된 document는 JQM 페이지 엘리먼트로서 로드 된 document의 DOM에 있는  첫번째 페이지가 select 될겁니다. 그래서 개발자는 로드된 페이지의 ID attribute와 child element를 잘 관리 해야 합니다.  그래야 DOM을 다룰 때 혼란스럽지 않습니다.

  • multipage document에 링크를 걸려면 그 링크에 반드시 data-ajax="false"를 하셔야 합니다. 이렇게 함으로서 Ajax request 에서 로드된 첫번째 페이지만 사용하는 제한을 벗어나서 full page를 사용하게 됩니다. 이 multi-page document를 로드할 수 있도록 하는 툴인 subpage plugin 이 있습니다.

  • jQuery Mobile-driven site에서 페이지에 의해 참조되는 unique assets는 page element 내부에 위치해 있어야 합니다. (page의 data-role attribute의 element). 예를 들어 별도의 페이지로 존재하는 styles와 scripts로의 링크 같은 경우 div 안에서 reference 될 수 있습니다. 어쨌든 바람직한 접근법은 특정 페이지가 로드될 때 특정 script를 실행하기 위해서 jQuery Mobile's page events를 사용하는 겁니다. NOTE : 이미 markup에서 특정된 data-url로 서버로부터 페이지를 return 받을 수 있습니다. 그리고 jQuery Mobile은 hash update를 할 겁니다. 이것은 여러분이 trailing slash로 directory path를 resolve 할 수 있도록 해 줍니다. 그래서 나중에 base url path가 사용될 수 있도록 합니다.

  • 역으로, non-unique assets (site 범위에서 사용되는)의 경우엔 HTML 도큐먼트의 <head> 섹션에서 reference 되어야 합니다. 적어도 page element의 밖에서 reference 되어야 합니다. 그래야지 그 script가 한번 이상 실행되는 것을 방지할 수 있습니다.

  • sub-hash url references에서 사용되는 "ui-page" key name은 여러분이 원하는대로 그 값을 세팅할 수 있습니다. 이 값은 jQuery.mobile.subPageUrlKey에 저장 됩니다.

  • push state plugin 이 enable 된 상태에서 내부나 외부 도큐먼트로부터 jQuery Mobile document로 back 될 때 어떤 브라우저는 잘못된 도큐먼트나 어떤 잘못된 원인이라고 해서 popstate 이벤트를 load하고 trigger 합니다. 여러분이 외부 document를 계속 링크를 걸어야 한다면 이 pushstate support를 disable 시키실 필요가 있습니다.

  • jQuery Mobile은 query parameter를 internal/embedded 페이지로 passing 하는 것을 지원하지 않습니다. 하지만 이 기능을 지원하도록 하는 두개의 플러그인이 있습니다. 가벼운 플러그인으로는 page params plugin이 있고 여러 기능을 제공하는 것으로는 jQuery Mobile router plugin이 있습니다. (이것은 backbone.js나 spine.js를 사용할 수 있도록 합니다.)

  • Back button behavior를 방지하기 위해 URL hash를 사용할 때 traditional anchor link(#foo)를 사용하는 것이 지원되지 않는 페이지를 jump down 하기 위해 page anchor를 사용합니다. scroll eventlistener trigger 하지 않고 특정 Y position을 scroll 하는 방법으로 silentScroll를 사용하는 방법이 있습니다.  yPos argument를 pass해서 그 Y location으로 scroll 할 수 있습니다.


반응형