'html5'에 해당되는 글 18건

  1. 2014.06.08 How to make cordova 3.X plugin (only android)
  2. 2014.04.05 querySelector 팁 몇가지
  3. 2014.01.27 cordova 3.X 사용방법정리
  4. 2014.01.18 도플광어의 backbone.js 강좌 - 2. model part2
  5. 2013.08.12 자바스크립트의 apply,call 그리고 bind
  6. 2012.11.08 도플광어의 Backbone.js 강좌 1. 모델
  7. 2012.11.04 jquery mobile 터치감 개선 시키기
  8. 2012.10.28 백본(Backbone.js) 강좌를 시작하며...

How to make cordova 3.X plugin (only android)

|

1. 플러그인 저장폴더 만들기(저장소)



다음과 같이 폴더를 구성합니다.



이 연습용 플러인 이름은 echo 입니다.


이렇게 만들어진 플러그인은 echo 폴더를 그대로 업로드 하는 방식으로 웹서버나 git을 통해서 간단하게 배포될수있습니다.


플러그인전체 구성을 정의해주는 plugin.xml 파일을 만들어 보겠습니다.


<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"

        xmlns:rim="http://www.blackberry.com/ns/widgets"

        xmlns:android="http://schemas.android.com/apk/res/android"

        id="플러그인고유식별자"

        version="0.0.1">

    <name>플러그인이름</name>

    <description>플러그인설명</description>

    <license>Apache 2.0</license>

    <keywords>플러그인 검섹키워드</keywords>


    <!-- android -->

    <platform name="android">

        <config-file target="res/xml/config.xml" parent="/*">

            <feature name="모듈이름(자바클래스이름)" >

                <param name="android-package" value="패키지이름을포함한모듈이름"/>

            </feature>

        </config-file>


        <source-file src="소스파일경로(pluin.xml파일이있는폴더기준)" target-dir="타겟경로(코도바프로잭트루트기준)" />

    </platform>

</plugin>


echo 플러그인을 위한 pulgin.xml 을 다음과 같이 만들어 보았습니다.


<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"

        xmlns:rim="http://www.blackberry.com/ns/widgets"

        xmlns:android="http://schemas.android.com/apk/res/android"

        id="com.gunpower.cordova.echo"

        version="0.0.1">

    <name>echo</name>

    <description>Cordova echo Plugin</description>

    <license>Apache 2.0</license>

    <keywords>cordova,echo</keywords>


    <!-- android -->

    <platform name="android">

        <config-file target="res/xml/config.xml" parent="/*">

            <feature name="Echo" >

                <param name="android-package" value="com.gunpower.cordova.echo.Echo"/>

            </feature>

        </config-file>


        <source-file src="src/android/Echo.java" target-dir="src/com/gunpower/cordova/echo" />

    </platform>

</plugin>



pluign.xml 파일에서 정의한 대로 src/android/Echo.java 경로로 파일을 작성합니다.


package com.gunpower.cordova.echo;


import org.apache.cordova.CallbackContext;

import org.apache.cordova.CordovaArgs;

import org.apache.cordova.CordovaInterface;

import org.apache.cordova.CordovaPlugin;

import org.apache.cordova.CordovaWebView;

import org.json.JSONArray;

import org.json.JSONException;


import android.util.Log;


public class Echo extends CordovaPlugin {

public static final String TAG = "Echo";


@Override

public void initialize(CordovaInterface cordova, CordovaWebView webView) {

// TODO Auto-generated method stub

super.initialize(cordova, webView);

Log.d(TAG, "echo pluin initialize");

}


@Override

public boolean execute(String action, String rawArgs,

CallbackContext callbackContext) throws JSONException {

// TODO Auto-generated method stub

return super.execute(action, rawArgs, callbackContext);

}


@Override

public boolean execute(String action, JSONArray args,

CallbackContext callbackContext) throws JSONException {

// TODO Auto-generated method stub

final String result = args.isNull(0) ? null : args.getString(0);

        

        if ("echo".equals(action)) {

        //인자 다시 자바스크립트로 전달하기 

            callbackContext.success(result);

            return true;

        } 

        

return super.execute(action, args, callbackContext);

}


@Override

public boolean execute(String action, CordovaArgs args,

CallbackContext callbackContext) throws JSONException {

// TODO Auto-generated method stub

return super.execute(action, args, callbackContext);

}


}



이상으로 플러그인 저장소가 만들어졌습니다.


2. 프로잭트에 플러그인 설치


cordova create myapp com.gbox.myapp myapp

cordova platform add android


myapp 으로 코도바 프로잭트를 만들고 플랫폼으로 안드로이드를 추가 합니다.




커멘드라인툴로 다음과같이 명령어를 주어서 플러그인을 myapp 프로잭트에 추가합니다.


cd myapp

cordova plugin add ../echo


3. 플러그인사용하기


cordova.exec 함수를 사용합니다.



자바스크립트쪽에서 cordova.exec 함수를 써서 Echo플러그인(service)의 echo 함수(action)를 호출하는 예 입니다.


cordova.exec(function(param) {

            console.log(param);

        }, function(err) {

            console.log('Nothing to echo.');

        }, "Echo", "echo", ['hello plugin!']);











And

querySelector 팁 몇가지

|

1. 체크박스나 레디오버튼 선택 항목 얻어내기


item 로 묶었을 경우


input[name=item]:checked


2. document 뿐만 아니라 특정 노드에서도 함수 사용이 가능합니다. 그러므로 좀더 빠른 탐색을 위해서는 document 보다는 근접한 부모노드에서 쿼리 함수를 실행하는 것이 더 좋습니다. document 는 트리의 root 입니다.



And

cordova 3.X 사용방법정리

|


cordova 3.X  에서는 커멘트라인 툴의 사용 순서가 매우 중요합니다.


1. 프로잭트 생성

2. 플랫폼 추가

3. 플러그인 추가

4. 플랫폼별 프로잭트 준비(prepare)


위 순서를 꼭지키셔야 제데로 프로잭트 생성이 됩니다.


1. 프로잭트 생성


cordova create myapp com.gbox.myapp myapp


프로 잭트 생성후 생선된 myapp폴더로 이동합니다.


2. 플랫폼 추가


안드로이드와 아이폰을 추가합니다.


cordova platform add ios android




3. 플러그인 추가


로그출력과 디바이스 정보를 얻어오는 플러그인을 추가 하도록 하겠습니다.


cordova plugin add org.apache.cordova.console org.apache.cordova.device





4. prepare


www/index.html 파일을 다음과 같이 수정합니다.


<!DOCTYPE html>

<html>

<head>

    <title>Device Properties Example</title>


    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>

    <script type="text/javascript" charset="utf-8">


        // Wait for device API libraries to load

        //

        document.addEventListener("deviceready", onDeviceReady, false);


        // device APIs are available

        //

        function onDeviceReady() {

            var element = document.getElementById('deviceProperties');

            element.innerHTML = 'Device Model: '    + device.model    + '<br />' +

                    'Device Cordova: '  + device.cordova  + '<br />' +

                    'Device Platform: ' + device.platform + '<br />' +

                    'Device UUID: '     + device.uuid     + '<br />' +

                    'Device Version: '  + device.version  + '<br />';


            console.log('hello console');

        }


    </script>

</head>

<body>

<p id="deviceProperties">Loading device properties...</p>

</body>

</html>


그런후에 다음 명령을 실행합니다.


cordova prepare




ios 로 싱행시키려면 xcode 로 myapp/platforms/ios/myapp.xcodeproj 파일을 엽니다. 그리고 run을 합니다.






android 로 실행시키려면 platform/android 을 adt 로 엽니다.





























And

도플광어의 backbone.js 강좌 - 2. model part2

|

이전 강좌에서 모델객체를 상속받아 객체를 초기화하고 기본적인 기능을 전반적으로 다뤄 보았습니다. 강좌를 쓴 시점이 저도 백본을 막 도입해서 쓴 시기라서 제데로 이해를 하지못하고 쓴부분이 있어서 하나 하나 다시 집어 보며 자세히 다시 써볼 계획입니다.


이번에는 백본오브잭트의 멤버에 접근하는 기초적인 방법에 대해서 자세히 알아보도록 하겠습니다.


백본으로 만든 오브잭트의 멤버에 접근하기 위해서는 get,set 함수를 사용할 수 있습니다.


                

                var Person = Backbone.Model.extend({

                    initialize: function() {

                        console.log('wellcome');

                        console.log(this.attributes.name);

                        //console.log(this.name);

                    }


                });


Person 은 변수이지만 동시에 객체를 선언하는 클래스입니다. 자바스크립트는 프로토타입방식의 객체지향언어이기때문에 이와같이 클래스 기반 언어와는 다른 특징이 있습니다.

백본의 Model.extend 함수로 백본모델로부터 상속받은 프로토타입핑클래스오브잭트(객체를 찍어낼수있는 객체 개념 정도?)를 만들수 있습니다.


                var person = new Person({name: 'tom', age: 37, children: ['lyn']});

 

Person을 가지고 인스턴스 오브잭트를 만들었습니다. person 은 Person의 인스턴스 입니다.



                console.log(person.get('name'));

                console.log(person.attributes.name);


get('name') 또는 attributes.name 로 값을 읽을 수 있습니다. 두 문장은 완전히 같은 일을 합니다.


person.attributes.job = 'js developer'

person.set('job','js developer');


set 함수로 값을 써넣을 수 있습니다.


person.name = 'tommy' 와 같이 값을 직접 넣을수도있지만 그렇게 되면 백본에 의해서 관리 밭을 수 없습니다.

예를 들어 이렇게 되면 name 이라는 멤버를 다루기 위해서 set,get 함수를 사용할 수 없습니다.(물론 person에 붙어서 존재는 합니다.)

그리고

attributes 로 직접 접근하는 것보다는 get,set 을 써서 간접적으로 접근하는 편이 좀더 유연하게 코드를 관리할거같습니다.




And

자바스크립트의 apply,call 그리고 bind

|

씨언어로 객체지향을 하던때가 있었습니다. 방법은 간단 했습니다.

함수의 첫번째 인자로 스트럭쳐 객체를 넣어주고 두번째 인자부터는 그 함수의 실제 인자 값을 넣어주는 것입니다.

사실 이방법은 씨뿐만 아니라 어셈블러 심지어 코볼이나 포트란에서도 비슷하게 썻었습니다.


자바스크립트의 함수도 기본적으로 그기능을 지원 해주는 함수객체의 멤버들이 있습니다.


apply

call


이 두가지 함수들은 서로 비슷한기능을 합니다. 다만 차이가 있다면 인자전달 방식을 배열로 해주는 apply 와 직접 해주는 call이 있습니다.


object.foo(인자들,..,...)

foo.call(object,인자들,..,...)

두개는 서로 완전히 일치합니다.




<script>


        var x = 10;


        function foo() {


            console.log(this.x);


        }


        foo();


        var obj = {x:12}; 


        foo.apply(obj); //12가 출력 됩니다.



        var obj2 = {x:18}


        foo.call(obj2); //18 가 출력 됩니다.



</script>



다음으로 인자들을 넘겨주는 예를 알아보도록 하겠습니다.




<script>


        var name = 'bill';


        function foo(msg,msg2) {


            console.log(msg + '  ' + msg2);


            console.log(this.name);


        }


        foo('normal call','default');


        var obj = {

            name : 'steve'

        }


        foo.call(obj,'call function','object'); //인자를 그냥 전달합니다.

        foo.apply(obj,['apply function','object']); //인자를 배열형태로 전달 합니다.



</script>



그럼 call이나 apply같은 건 왜 쓰일까요?


평소에는 쓸이유가 거의 없지만 객체를 상속받았을때 부모클래스의 함수를 호출하고 싶을때 응용할 수 있습니다.


show : function {

superclass.show.call(this);

}




bind 에 대해서 알아보도록 합시다.


기본적으로 핸들러로 호출되는 람다함수들의 this는 전역객체이기 때문에

타이머라든지 이밴트 핸들러의 콜백함수로 호출이될때도 특정 객체와 연결하여 this를 유지 하고싶을때 bind 함수를 사용해서 해결할 수 있습니다.


fun.bind(object,arg1,....argn)


<script>


        var a = 'global this'


        function test() {

            this.a = 'that this';


            function test2() {


                console.log(this.a);


            }



            var _test2 = test2.bind(this);


//global this 가 찍힌다.

            test2();

            setTimeout(test2,1);


            //아래 2개는 모두 같은 결과

            //test2.apply(this);

            //_test2();


//that this 가 찍힌다.

            //타이머같은 콜백 함수로도 응용 가능함

            setTimeout(_test2,1);


        }


        var obj = new test();


</script>


bind 는 인자로 넘겨준 객체에 연결된 새로운 함수객체를 반환한다.

콜백 함수를 특정 객체와 연결하고 싶을 때 사용한다.

처음에 호출된 test2  에서 사용된 this는 전역 객체 이지만 두번째 bind를 통해서 만들어진 _test2 에 있는 this 는 test 함수로컬 객체가 된다.




참고 : 


call ,apply 에 관한글

http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx


bind 에 관한글

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind








And

도플광어의 Backbone.js 강좌 1. 모델

|


1. 모델 클래스 만들기


Model 객체로부터 상속받아서 새로운 클래스를정의 할수있다.


var Person = Backbone.Model.extend({

        initialize: function(data) {

            console.log('welcome backbone');

            console.log('hello ' + data.name);

        }

    });



스크립트언어에 익숙하지않다면 약간 이상해보일수도있지만 이것은 스크립트언어이기때문에 가능한 문법이다. 컴파일러형언어에서는 클래스와 객체가 명확히 나누어져있다. 클래스는 붕어빵틀역역활을 하고 인스턴스 객체는 그틀로 만들어진 붕어빠같은것이지만

스크립트언어에서는 붕어빵틀과 붕어빵의 구분이 명확하지않다. 스크립트언어에서는 인스턴스만 객체 있을뿐이다. 왜냐하면 컴파일과 실행이 따로 분리되어있지않고 항상실행상태로 간주되기때문이다. 코딩을 하는중간에도 실행중인것이다. 그래서 틀이라는 개념이 컴파일러형언어처럼 경직되어있지않다.


그래서 위와같이 어떤 함수 객체가 새로운 함수 객체를 만들어 반환할수도있고 이미만들어진 객체에 새로운 멤버데이터가 추가 될수도있는것이다.

Person은 인스턴스객체 이면서 동시에 클래스가 될수도있다.(c++ 프로그래머만 알아들을수있는 말?)


Peroson이 새로운 인스턴스를 만들려면 다음과 같이한다.


var somebody = new Person({name:'tommy'});


{name:'tommy'} 은 생성자에 넘겨주는 인자와 같은 역활을한다. 이 인자는 그대로 initialize함수의 인자로 전달된다.


2. 멤버 다루기


멤버 변수에 접근하는 방법은


내부에서는 

this.attributes.name

this.get('name'); 두가지로 가능하다.


외부에서접근은 

somebody.attributes.name; 

somebody.get('name');


역시 두가지 모두 가능하다.


somebody.toJSON();

json형태로 모델데이터를 내보낼수도 있다.


3. initialize 함수


생성자에서 넣어준값이 파라메터로 넘어올수있고 또는 함수내에서 this.attributes 형태로 받아볼수있다.

4. defaults 구조체


초기 값들을 설정해주는 일종의 초기화 객체이다. 단순히 객체만 값을 초기화 해줄목적이면 initialize에서보다 defaults에서 단순하게 정의만 해주는게 낫다.


Person = Backbone.Model.extend(

 initialize: function() { console.log('wellcome' + this.get('name')); }, 

 defaults: { name: 'lsz', age: 42, children: [] }

 });


이렇게 하면 name의 기본값은 'lsz가된다.


5. 리스너


값이 바뀌면 연결해서 함수가 자동으로 호출되게 하는 개념이다.


function start() {

    Person = Backbone.Model.extend({

        initialize: function() {

            console.log('wellcome' + this.get('name'));

            /*

             * 리스너 설정 예 

             */

            this.bind("change:name", function() {

                console.log('change : ' + this.get('name'));

            });

            this.bind('error',function(model,error) {

                console.log('error occur~');

                console.log(model);

                console.log(error);

            })


        },

        defaults: {

            name: 'lsz',

            age: 42,

            children: []

        },

        replaceNameAttr: function(_name) {

            this.set({name:_name});

        },

        validate : function(attributes) {

          if(attributes.age < 0) {

              return 'u cant have negative age!';

          }  

        }

    });

    var person = new Person();

    person.set({name: 'tommy'});

    console.log(person.get('name'));

    person.set({age:-2});


}


bind 함수를 통해서 값과 변화가 있을때 연결할 함수를 정한다. 예제에서는 name값이 바뀌면 자동으로 인자로 연결해준 함수가 호출된다.


validate 함수를 이용해서 멤버변수값들의 범위를 지정할수있다. 만약 적절하지못한 범위의 값이 들어오면 해당 메시지를 보내거나 특정한 작업을 수행할수있다. 여기서는 age가 음수값이 나오면 오류 메씨지를 리턴하도록 했다.


bind 에서 'error'로 묶어진 함수에서 처리가된다. 묶어진 함수의 첫번째 인자로는 에러가 유발된 객체가 오고 두번째에는 validate에서 넘어온 메씨지나 오브잭트가 온다.


6. 상속


Person = Backbone.Model.extend({

        initialize: function(data) {

            console.log('init person');


        },

        test: function() {

            console.log('test!' + this.attributes.name);

        },

        test2: function() {

            console.log('person test!' + this.attributes.name);

        }

    });


    Soldier = Person.extend({

        initialize: function(data) {

            console.log('init soldier');

        },

        test2: function() {

            console.log('Soldier test!' + this.attributes.name);

        }


    });

    

    var soldier = new Soldier({name: 'tom', age: 27});


    soldier.test();

    soldier.test2();

    

    var person = new Person({name: 'jery', age: 27});

    person.test2();



Solider 를 Person을 상속받아서 만들었다. 이렇게 만들어진 soldier 는 test함수를 정의 하지 않았더라도 부모의 test 함수를 호출하게된다.






And

jquery mobile 터치감 개선 시키기

|


기본적으로 클릭이밴트는 약 300ms의 딜레이 시간을 가지게되므로 사용자 반응성이 매우 취약하다고 볼수있다.


그래서...


터치감 개선의 핵심은 click 이밴트를 사용하지않고 touchstart 사용하는것에서 시작한다.


그러나 데스크탑에서도 동시에 서비스를 하고싶다면 터치이밴트가 동작하지않는 문제가 있다.


vmousedown이밴트를 사용하면 데스크탑에서 마우스로 터치 디바이스에서는 touchstart자동으로 바꿔서 전달하게된다.




리턴값을 false 로 하면 부모로 이밴트가 전달되는것과 기본 이밴트처리가되는것을 막아준다.


그렇지만 이것으로 부족하다 jqm 에서 a태그 또는 button 태그는 touch가 일어나면 vclick을 강제로 한번씩 발생시킨다.

그래서 아래와 같이 vclick이밴트를 따로 한번 더 처리하여준다. 





li 의 하위 단계에있는 a태그에 들어오는 vclick이밴트가 더이상 전파되지않도록 하고 기본적인으로 해주는 동작들을 금지 시킨다.(핸들러 함수객체에서  false값을 반환하게 해서... ) 그렇지않으면 의도하지않게 vclick이밴트가 한번더 들어오게된다. 그렇게 되면 버튼이 두번눌러지는등의 오동작이 일어날수있다.


-예제 소스


무제 폴더.zip














And

백본(Backbone.js) 강좌를 시작하며...

|



사실 내가 백본에 관심을 가지게 된것은 우연한것은 아니였다.

객체지향 페러다임에 염증이난 상태에서 펑션널 프로그래밍 페러다임에 푹빠져있을때 

내가 하는 코드가 해면체같다는 느낌을 받았다.


VC(뷰 와 컨트롤) 만 가지고 프로그램을 하면 쉽게 모든것을 할수있다는 착각도 잠시했던거같다.


일리히트엔진에 빠져서 보낸날들동안 집착했던 모델을 버리고 그동안 잊고살았던 뷰와 컨트롤과 함께 즐거운시간을 보내던나는

너무 소모적인 코드가 나온다는 사실을 깨닭기 까지는 그다지오랜시간이 필요하지는 않았다.


일리히트엔진의 장점이자 최대 단점은 모델이 너무 견고하다는 점이다.

모델이 견고할(비중이 클...)경우를 쉽게 설명하자면 이렇다.


건물을 지어야하는데 골격이 튼튼하다면 굉장히 빠르고 쉽게 높이 건물을 올릴수있다.

그러나 건물의 형태는 괭장히 획일적이고 밋밋하게 지어야만한다.(한마디로 안이쁘다)


그런면에서 일리히트엔진으로 작업을 했던 동안 나는 매우 큰 딜래마에 빠져들곤했다. 게임이라는 매우 불안정하고 다루기 힘든 주조물을 경직된 틀안에 가두어 개발하는게 과연 정답일까?


물론 학생들이 모델에 대한 이해를 돕는데는 좋지만 이것이과연 실용적으로 사용될수있을런지는 계속 의문이 많았다.


그래서 실험적으로 아주 반대의 길을 가보고싶었다. 재물은 바로 웹(html5)이라는 아직은 음지에 머물러있는(물론 게임쪽에서만) 신물질이였다.


이것으로 처음한 실험이 모델을 완전 배제한체 프로잭트를 진행해보는것이였다. 뷰만 컨트롤만 가지고 개발을 하는것이다.

아주 빠른속도로 결과물이 나왔지만 매우 불안정해서 나오자 마자 바로 사라져버리는것이 문제였다.

즉 프로잭트가 진행되는 동안에 코드들이 모두 부패해버려 결과물이 나올때가 되면 이미 완전히 모든 코드가 썩어버려서 더이상 프로잭트를 진행할수가없었다.



모델없이 개발하는것은 마치 아키라에서 데츠오가 궁극의 힘을 얻고도 제어가 안되어 파멸했던 상황과 같다.




MVC 의 세가지 요소의 적절한 배합이 중요하다는것을 정말 뼈아프게 느꼇다. 그리고 아직은 내가 배워야할게 너무나 많다는 사실에 한편은 실망스럽기도 하지만 다른 한편으로는 이제 막 바다가에 나온 소년처럼 설레이기도한다.


원자로로 치자면 VC가 발생시키는  온도를 제어 할수 있는 제어봉이 바로 M 이다.


이것을 기억하며 Backbone.js를 시작하자...












And
prev | 1 | 2 | next