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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

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);



반응형

수요일의 FAQ - 070412 -

2012. 7. 8. 00:44 | Posted by 솔웅


반응형
Posted on . Written by


오늘은 수요일이자 독립기념일입니다. 독립기념일의 FAQ를 시작하겠습니다. 아래에 자주 나오는 질문 5가지와 그 답변이 있습니다.


1. ‘require(“file”)’ 과 ‘require “file”의 다른 점이 뭔가요?


여러분은 require API 에서 아래 두가지 방법을 보셨을 겁니다.

-- Example #1
local json = require( "json" )

-- Example #2
local json = require "json"


일반적으로 함수는 pass 하게 될 인자(argument)들을 요구합니다. 하지만 루아에서는 약간의

예외가 있습니다. 만약에 함수가 단 한개만의 인자만 가지고 있다면 (그것이 스트링이던

테이블이던) 괄호는 옵션 사항입니다. 이 규칙은 print 구문이나 한개의 인자(스트링이든

테이블이든) 를 받는 다른 함수에도 마찬가지로 적용됩니다.



2. 우리는 코로나의 변수와 관련해서 많은 complain을 받습니다.

분명히 변수에 값을 대입했는데 인덱스나 함수에서는 nil이라고 하니까

분명히 버그가 있을 거라는 겁니다.

 

코로나에서 사용하는 루아라는 언어로 프로그래밍을 하다보면 가장 흔하게 부딪히는 문제점이

nil 에러입니다.

다른 언어와는 다르게 루아는 변수를 사용하기 전에 선언해야 하지 않습니다.

변수에 값을 대입하지 않으면 루아는 그 값을 그냥 nil로 처리합니다.

nil 에러가 일어나는 일반적인 원인은 변수나 함수가 out of scope 일 경우가 많습니다.

여러분이 변수나 함수를 local로 정의해서 메모리를 점유하게 만들면 이런 경우가 종종

발생할 수 있습니다.

루아에서 로컬 변수의 scope은 그것이 선언된 곳 (예 main.lua)에 한정돼 있습니다.

다른 lua 파일에서 그 로컬 변수에 접근하려고 할 경우 이 nil 에러가 발생합니다.

또한 로컬 변수는 그것이 정의(선언)된 이후에 참조가 가능합니다. 변수가 선언되기 이전에

이 변수를 참조하려고 한다면 여기서도 nil 에러가 일어납니다.

 

저는 대개 로컬 변수를 루아 파일의 맨 첫 부분에 정의를 합니다. 그러면 나중에 그 변수에

접근이 가능하니까요.


-- This code block won't work because the addNumbers
-- function is called before it's been defined

local addNumbers -- forward reference

print( addNumbers( 5, 6 ) )

function addNumbers( num1, num2 )
return num1 + num2
end


-- This code block works because the addNumbers
-- function is called after it's been defined

local addNumbers -- forward reference

timer.performWithDelay( 1, function()print( addNumbers( 5, 6 ) ) end )

function addNumbers( num1, num2 )
return num1 + num2
end

 

timer.performWithDelayaddNumbers 함수가 정의 된 후에 execution code에서 addNumbers

함수를 call 합니다. 여기서 그 함수로 포인터가 access 하기 위해local addNumbers 구문이

필요합니다.


한번 변수 선언할 때 local을 없애고 어떻게 되는지 보세요. 그것이 정의 되기 전에 함수를

call 하게 되면 마찬가지로 에러가 날 겁니다. 그 변수나 함수가 nil (out of scope)인지

아닌지 체크해 보기 위해서 print 구문을 사용하셔도 됩니다. 에러가 났을 경우 정확히

어디에서 에러가 났는지 찾아보는데 도움이 될 겁니다. 변수나 함수들을 print out 할 때

콤마 , 를 사용하세요. 콤마와 함께 프린트 하게 되면 nil 밸류와 함께 함수와 테이블

addresses를 보여 줄 겁니다.



3. Facebook 인터페이스에 대한 문서는 어디에서 볼 수 있죠?


코로나의 페이스북 인터페이스는 Facebook Graph API를 사용합니다.

여기에서 코로나 페이스북 문서에 대한 인터페이스 정보를 찾아보실 수 있습니다.

Facebook API페이지의 페이스북 파라미터 정보도 찾아 보실 수 있습니다.
그리고 우리의 Jonathan Beebe의 아주 훌륭한 페이스북 튜토리얼도 참조하세요.
Implementing Facebook Single Sign-on and Uploading Photos to Facebook.

코로나 SDK에 포함된 페이스북 샘플 앱도 잊지 마시구요.



4. baseDirectory에 subdirectory 이름을 add 해서 이미지를 로드하려고

합니다.그런데 제대로 로드되지가 않네요. 뭐가 잘못된거죠?


baseDirectory
인자(argument)는 Corona API에서 아주 많이 사용되는데요.

이는 asset들에 대한 base directory를 가리키고 있습니다.

이 base directory는 사전 정의된 아래 3개 constants (상수) 중에 하나이어야 합니다.

system.ResourceDirectory,system.TemporaryDirectory, system.DocumentsDirectory

아무것도 특정하지 않으면system.ResourceDirectory 가 디폴트로 사용됩니다.


그 subdirectory에 있는 asset에 접근 하시려면 이 subdirectory는 파일 이름에 추가

하셔야 합니다. baseDirectory에 추가하시면 안 됩니다.


아래 예제가 있습니다.

local IMG_DIR = "images/"
-- Loads image from Resource directory
local image = display.newImage( "apple.png", 50, 50 )

-- Loads image from Resource directory
local image = display.newImage( "apple.png", system.ResourceDirectory, 50, 50 )

-- Loads image from images subfolder in Resource directory
local image = display.newImage( IMG_DIR .. "apple.png", 50, 50, true )

-- Loads image from images subfolder in Documents directory
local image = display.newImage( IMG_DIR .. "apple.png",
system
.DocumentsDirectory, 50, 50 )

subfolder 이름을 구분하는 구분자로는 . 가 아닌 / 를 사용한다는 것을 기억하세요.

. 는 require 에서 사용됩니다. 그리고 그 나머지에서는 / 를 사용합니다.



5. 이건 질문은 아닌데요. Lua 에만 있는 특별한 기능입니다.
함수에서 return 하는 return 값이 복수개가 될 수 있는 기능입니다.


루아는 함수에서 multiple value들을 return 할 수 있는 몇 안되는 언어중 하나입니다.

에러 메세지같은 multiple value들을 return 해야 할 때 편리하게 사용됩니다.

이 기능을 이용해 여러 진보된 기능의 루아 함수들을 많이 보실 수 있을 겁니다.

-- The string.find API returns the start and end of the found string
print( string.find( "Hello Corona user", "Corona" ) ) -- prints 7 and 12

여러분이 만드는 함수에도 이 기능을 사용하실 수 있습니다.

myRect = display.newRect( 0, 0, 25, 50 )

local function getWidthHeight( object )
return object.width, object.height
end

print( getWidthHeight( myRect ) ) -- print 25 and 50

여기까지가 오늘의 질문들입니다.

조금이라도 새로운 것을 배울 수 있는 유익한 시간이었길 바랍니다.



반응형

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 이 있습니다.


반응형