06月09日 

jQTouch

jQTouch – 画面遷移の前にデータ処理

jQTouchネタが多いですね。案件で蓄積してるノウハウの小出しですw

あるボタンやリストをタップした時、画面が遷移する前にデータの取得やら処理を行いたい、という状況は多いかと思います。タップのイベントを拾って処理して、処理後に遷移すればOK。ということで

JAVASCRIPT:
  1. $('#hoge').tap(function() {
  2.     // 処理
  3.  
  4.     jQT.goTo('#next', 'slide');
  5. });

上のネタはどこかのブログでも記事にされていたのを見たことがあるのですが、実はこれだけだと連打や他のボタンをタップしてしまうと画面遷移でブッ飛びます…orz
LocalDBに保存してる分でも後処理によってはタイムラグも発生するし、Ajaxで外部のDBサーバーに問い合わせするとボチボチ時間が掛かったりして余裕で連続タップされてしまうわけで。

こんな時は単純にフラグ立てちゃえばいいですね。

JAVASCRIPT:
  1. $('#hoge').tap(function() {
  2.     if (!tapNow) {
  3.         tapNow = true;
  4.  
  5.         // 処理
  6.     }
  7. });

フラグを倒すタイミングはページの遷移が終了した時で良いので

JAVASCRIPT:
  1. $('body > div').bind('pageAnimationEnd', function(event, info) {
  2.     touchNow = false;
  3. });

で一括でフラグを倒すことが出来ます(エラー発生時などは個別に対応が必要ですが)

さらに、slideを繰り返すとgoBackでリストの.activeが解除されない(?)という謎なアレがあるので、ついでに

JAVASCRIPT:
  1. $('body> div').bind('pageAnimationEnd', function(event, info) {
  2.     touchNow = false;
  3.  
  4.     if (info.direction == "in") {
  5.         $(this).find('a.active').removeClass('active');
  6.     }
  7. });

としておけば解除されますよ。

という小ネタでした。

06月02日 

jQTouch

jQTouchちらつき対応(6/4追記)

ここ数日jQTouchでiPad用ローカルアプリを作ってるんですが、jQTouchオフィシャルではiPad用に2カラムを制御するための仕様策定が進んでいるようですね。

お手軽にiPhone・iPadの動きを伴ったjQTouchですが、画面遷移時に遷移後の画面が一瞬チラついたりして少し微妙な点があります。ソースを追って見たところ、アニメーションにはCSS3のアニメーション機能を使っているようです。
アニメーションを開始させるタイミングで、適したCSSをJSで指定してあげることで要素をアニメーションさせ、終わった段階でアニメーション用CSSを外してあげる。

ちらつきが発生する原因としては、アニメーション終了でCSSを外す時に同時にdisplay:noneになるのですが、ブラウザの仕様(?)で一瞬ちらつくみたいです。

ということで色々と対策を考えてdisplay:noneだけタイミングをずらしてみたりとか試してみたのですが上手く行かず。。。で、ググって見たら出てきました…orz

jqtouch.js

JAVASCRIPT:
  1. function animatePages(from, ...
  2.  
  3. scrollTo(0, 0);
  4.  
  5. // 追加ここから
  6. var toStart = 'translateX(' + (backwards ? '-' : '') + window.innerWidth + 'px)';
  7. // 6/4追記ここから
  8. if (animation.name == 'slideup' && backwards != true) {
  9.     toStart = 'translateY(0px)';
  10. }
  11. // 追記ここまで
  12. fromPage.css( 'webkitTransform', toStart );
  13. // 追加ここまで
  14.  
  15. var callback = function(event) {
  16.     // 追加1行
  17.     fromPage.css( 'webkitTransform', '');
  18.  
  19.     if (animation)

(元ネタのページは失念です。。。)

元のソースに手を入れるのは気が引けるところですが、これでバッチリちらつきを無くすことが出来ます。お悩みの方は是非お試し下さいませ。

(6/4追記)
slideupのアニメーションで、遷移前のページが消えてしまう為、ソース改変の一部を変更しました。
ちなみにドキュメントには書かれてない(?)と思うんですが、縦スライドさせたいときは「slideup」ですが、任意で横スライドさせたい場合は「slide」です。

05月31日 

javascript

jQueryでアニメーションさせるとき


jQueryに限った話では無いかとも思うのですが…

ブロック要素をスライドさせたりしてアニメーションさせる時、表示がガタガタと乱れて見苦しい時があります。そんな時は…

アニメーションさせるブロック要素に「overflow:hidden」を指定するとよろし。というTips

スクロールバーが既に出てるブロック要素なら、アニメーションの開始直前に指定してあげれば見た目上にはあまり違和感無しです。
んでここからが大事で、iPhone用のWebアプリを作る時にそれっぽいUIを実現することが出来る「jQTouch」。画面遷移アニメーションで結構ガタつきます。
そんな時にもこのTips、画面単位のDIVにoverflow:hiddenを指定してあげると(多少w)改善されます。

ちなみにローカルアプリをHTML+CSS+JSで構築し、DBにはHTML5のClient-side Databaseを使いましたが、PhoneGapでアプリ化しても何のトラブルも無くiPadアプリとして使用できました。スゲー。
(結局は色々な問題点があってWebアプリとしてサーバー上にリソースを置くことになったんですけどね…)

PhoneGap使えばGPS拾ったりコンタクトリストからデータを引っ張ったり、カメラを起動したりと結構色々な事が出来るので、UIが少し緩かっても大丈夫とか高機能性を求めないのであればオススメですよー(って何記事?)

03月23日 

javascript

.coder Session1で喋ってきました

本当に最近更新できてないです。。。
ちょっと技術ネタにコダワリすぎてる様な気も…いかんいかん。

さて先日、クソ忙しい中記念すべき第1回が開催されたデザイナー・コーダー向けLTイベント.coder Session1で喋ってきました。開始直後はトラブルがあったものの、会は進み自分の番に。
今回は会場の照明が一括制御で、全On/全Offということもあり、発表時は真っ暗(スライドがあるので)。おかげで人の目を気にしなくてもいい、という精神的にとても楽な状況だったので、いつもよりスラスラ喋れること!もう次回からは「会場真っ暗必須でお願いします」ですw

内容については、デザイナー・コーダー向けとはほど遠いセキュリティ関係のお話。最近ちょくちょく脆弱性が報告される「CSRF(クロスサイトスクリプティングフォージェリ)」について話してきました。攻撃の原理と対策方法。jQueryで簡単に実装するには、という流れで小難しい分野だったのですが、意外とシステム寄りの参加者もいらっしゃって「セキュリティ対策の再認識になりました」と言って頂けたりでお役に立てて何よりでした。

今回のスライドは公開する予定が無いのですが、別のイベントでもご依頼頂ければ喋ってみたいと思います。
お気軽にどうぞ~

あ、その際の会場は真っ暗でお願いしますw

03月07日 

javascript

.coder(どっとこーだー)Session1で喋ります

関西Javascriptの雄、noriさんが中心となってコーダー/デザイナー向けLT勉強会「.coder(どっとこーだー)」を主催される、ということでSession1テーマ「Javascript」で喋ることになりました。

最初はjQuery1.4で追加された機能でもタラタラ並べ上げようかとも思ってたんですが、なんかそれも面白くない。
O3Dで3D描画とかも考えたけど、LTだと「こんなん出来ますよ」が関の山。
フロントだけで完結しちゃうデザイン周りを触るようなJSのお話は誰かがしてくれるだろうし。

んで、これはある方とお話してる時にチラリと言われたことなのだけど、「サーバー側を理解しているJSer」。
ということでサーバーとのやりとりをAjax通信で行うときのTipsを題材にしようと思いました。

サーバー側とのやりとりで、小ネタを喋るより先にセキュリティが大事でしょ、ということで、そこら辺の話をさくっとしようと思います。
やっぱり肝はサーバー側の処理になってくるんですが、こういったセキュリティ対策が必要、という認識をフロント側も持っているだけで、実装の漏れを防ぐことが出来ますしね(Ajax通信でやりとりをしたことがないサーバー側担当って意外に多い)

残念ながら既に定員マックス(というかオーバー)なので追加での参加は難しいかと思いますが。。。
参加される皆様、相変わらず小難しい話しますが、お付き合い下さいませ。

Google独自の3D「O3D」で全方位パノラマを再生してみる

HTML5規格ではブラウザ上で3Dがウンタラ、とかありますが、イマイチ資料など目に付かず。

ブラウザでイケる3D APIといえば、MozillaのCanvas:3Dか、GoogleのO3D。んで、ようやく策定の始まった(?)WebGLと。
HTML5はWebGL規格になるのかな?誰かkwsk。

0203ま、そんなん待ってても仕方ないので、いっちょ実装してみることに。
互換性を大事にAPIを単純にしてしまってるCanvas:3Dではなく、結構エグいことが出来るO3Dを選択してみました。O3Dのイケてるところは、GPUを活用できちゃう、という点。
Actionscript3+Papervision3Dでなくても、高速に綺麗に3Dの描画が行けるんちゃうか?ということなんですなぁ。

ということで、実装した感じは…
の前に、再生するにはプラグインをインストールする必要があるので、まずは

http://code.google.com/intl/ja/apis/o3d/

上記URLページの右側にある「O3Dのダウンロード」を押してプラグインをインストールした後、いったんブラウザを再起動してから、

http://www.studio-bloom.net/public/o3d_pano/

をご覧くださいませ(環境によっては表示されない場合もあります)。
あぁ、ChromeかFirefoxでお願いしますよ。Mac?知らん。

画像の読み込みが終わるまでグレーになってますが、しばらくお待ちください。マウスでクリックしたまま動かすとグリグリできます。

平面プリミティブ6面を配置して、それぞれにテクスチャを貼り付けてるんですが、平面同士の境目が見えてしまってるんですよね…(PV3Dでは境目も出ないし動作が軽い)

境目を消すには、正方体プリミティブを作って各面にテクスチャを貼ることで解決できないかな?と思いつつ。ただ正方体プリミティブの面ごとにテクスチャを変える方法がイマイチ掴めず。。。ちょっと描画かプリミティブのパラメータをいじったらイイ感じにならないかな?と思ったりしてます。

結果としては、画質なんかはイイ感じなんだけど、GPU使ったりしてる割には妙に重い。PCの問題なのか、ブラウザの問題なのか?V8エンジンを使用すると速くなるよ、とのTipsもあるんだけど…(Chromeだけかよ!)

しかも、なぜかうちのノートPCではテクスチャ画像を読んでくれなくて(オフィシャルのサンプルも)再生できませんでした。
ちょっとここら辺はAPIの熟成を待つしかなさそうですねぇ。。。

再生するにはプラグインの導入が必要だし、一般的に使用されるようになるか、というのは疑問ちょっと疑問。WebGLも策定から各ブラウザへの実装がどれほど時間の掛かることか、と考えると、現状のAS3+PV3Dはしばらく鉄板な気がします。

01月27日 

javascript

jQuery1.4いいね!~$.proxy編~ とJSで動的に画像読込

jQueryも1.4にバージョンアップして、高速化しただけじゃなくていろいろ機能追加されてるそうで。
偶然KAYACさんのところで紹介されてて、感動してしまった機能をここでもご紹介。

それは…

$.proxy()

Takes a function and returns a new one that will always have a particular scope.
ということなので、関数を与えると特定のスコープを常に持った新しい関数を返しますよ、という訳であってるんだと思うんですが…

本家のサイトにあるサンプルでは

JAVASCRIPT:
  1. var obj = {
  2.   name: "John",
  3.   test: function() {
  4.     alert( this.name );
  5.     $("#test").unbind("click", obj.test);
  6.   }
  7. };
  8.  
  9. $("#test").click( jQuery.proxy( obj, "test" ) );

はい、便利ですね~

と、ちょうど作ってたのがJSでの動的な画像の読み込み。
FirefoxやChromeだと、普通に要素のsrc属性に画像のURLを指定してあげれば読み込み完了と同時に画像を差し替えてくれるのですが、そこはホラ、IEですよ、奥さん。

Imageオブジェクトのcompleteプロパティを監視してtrueになったときにsrcに突っ込んであげないと画像を切り替えてくれない、というオマケ付きな訳なんですよ…orz

そこで、setIntervalで定期的にループさせてプロパティを監視することに。
ということは読み込みが完了したときにはclearIntervalでループを止めないといけないですよね~
そんな時に、この$.proxy()が役に立つ!

JAVASCRIPT:
  1. function ImageLoad() {
  2.     this.img=new Image();
  3. };
  4.  
  5. ImageLoad.prototype = {
  6.     changeImage:function(e, s) {
  7.         this.elm = e;
  8.        
  9.         this.img.src = s;
  10.        
  11.         this.timer = setInterval($.proxy(function() {
  12.             if (this.img.complete) {
  13.                 $(this.elm).attr('src', this.img.src);
  14.                 clearInterval(this.timer);
  15.                
  16.             }
  17.         }, this), 200);
  18.     }
  19. };
  20.  
  21. var img = new ImageLoad();
  22.  
  23. $('hoge').click(function() {
  24.         img.changeImage('#image', 'path/to/image.jpg');
  25. });

こんな感じで使えます。
$.proxy()が無いと、thisのスコープが変わっちゃうので、なんか適当な変数を用意して、とかちょっと力業で実装したりかと思うのですが、綺麗にコーディングできますね!

いや~いいですね!jQuery1.4!
他にも素敵な機能追加があったりするので、また紹介できれば。

01月21日 

javascript

ウェブテコでお話します

神戸で毎月開催されているウェブの勉強会にてピーチクパーチクります。

今回はテーマが”HTML5&CSS3”ということで、「なんかそこら辺に絡む事を話せや」とお誘い頂いたので、Client-side Database strageについてお話することにしました。

HTML5から、Webのシステムで今や必須とも言えるデータベース(DB)を、サーバー上でなくローカルPC上で使えるようにしましょう、といった技術なんです。
めちゃくちゃ乱暴な言い方をすればCookieの高機能版(どちらかというと同じくHTML5で追加されたキーバリューストアという機能の方がCookieには近いのだが…)。

よく似た技術で、Google Gearにもこの機能がありましたね。結局HTML5で標準化されるのに伴ってGearの方は終了してしまいましたが。。。
「ローカルでもWebシステムが使用できる」という触れ込みだったかと思うのですが、これだけデバイスやインフラが整ってくると、あまりローカルに環境を持ってこなくても…と思ったりもしてしまう訳なんですが…

よく考えてみたら、iPhoneにもSafariが搭載されてるので(しかもClient-side DBは現在Safariにしか実装されてない)、簡単なiPhoneアプリくらいだと作れてしまうではないか、と。

ということで、今回の内容は簡単にClient-side DBの説明と、DBを操作するためのSQLのこれまた簡単な解説、クエリを投げるjsのコード紹介、んでこのDBを使って書籍を管理する超簡単なアプリの実演という流れで行こうと思ってます。
本当はアプリの実際のコードを追って行こうかとも思ったんですが、案外ボチボチな行数になってしまったので、実際のソースコードは配布してもらって、各自で見て頂くことになるかと思われ。
jQueryもちょこっと使ったりjsの説明は一切無しなので、そこらへんの知識が無いとツラいと思われますが、時間のこともあるので割愛御免。

興味のある方は是非ご参加ください。

日時:1/23(土) 13:30~17:30
場所:神戸元町 インキュベーションオフィスエリンサーブ KCCビル3F会議室
参加費:500円(運営費)
http://webteko.jp/

懇親会もありますので、そちらも是非w

01月06日 

javascript

javascriptで関数の引数を不定にしてみる

あけましておめでとうございます。
本年もよろしくお願いいたします。

新年一発目のエントリは技術ネタ、というかTipsというか、あんまり使いどころがよく分からんというか。。。

javascriptは関数の引数に変数を与えなくても

JAVASCRIPT:
  1. function hoge() {
  2.      var arg1 = arguments[0];
  3.      var arg2 = arguments[1];
  4.  
  5.     return arg1+arg2;
  6. }
  7.  
  8. var sum = hoge(1, 2);

なんて感じで引数を取ることが出来ちゃうんですけれども、これだと引数の順番が固定になっちゃったりで、いまいちフレキシブルではないので、もうちょっと柔軟に出来んもんか、と考えたのがオブジェクトを渡す方法。

JAVASCRIPT:
  1. function hoge(args) {
  2.     var arg1 = args["arg1"];
  3.     var arg2 = args["arg2"];
  4.  
  5.     return arg1 + arg2;
  6. }
  7.  
  8. var sum = hoge({"arg1":1, "arg2":2});

キーと変数渡してやればどうでしょ?ということで。

で、何の役に立つねん?というとこなんですが、実行したい関数を変数で与えて、その引数が関数毎に微妙に違うけど、処理は共通、みたいな。ややこしや。

JAVASCRIPT:
  1. var funcs = {
  2.     //var getMemberPhoto = function(args) { <- 文法ミス
  3.     getMemberPhoto : function(args) {
  4.         var params = {
  5.             member_id:args["member_id"]
  6.         };
  7.         ...
  8.     },
  9.     //var getCategoryPhoto = function(args) { <- 文法ミス
  10.     getCategoryPhoto : function(args) {
  11.         var params = {
  12.             category_id:args["category_id"]
  13.         };
  14.         ...
  15.     },
  16.     //var getPhotoByPeriod = function(args) { <- 文法ミス
  17.     getPhotoByPeriod : function(args) {
  18.         var params = {
  19.             start_date:args["start_date"],
  20.             end_date:args["end_date"]
  21.         };
  22.         ....
  23.     }
  24. };
  25.  
  26. function getPhotos() {
  27.     var func = $("input[name=select_func]:checked").val();
  28.     var params = {};
  29.     $("#" + func + " .params").each(function() {
  30.         params[$(this).attr("name")] = $(this).val();
  31.     });
  32.  
  33.     if (typeof funcs[func] == "function") {
  34.         funcs[func](params);
  35.     }
  36. }

(追記)JSの文法ミスってました(汗)

HTML:
  1. <label><input type="radio" name="select_func" value="getMemberPhoto" />指定メンバーの画像取得
  2. <label><input type="radio" name="select_func" value="getCategoryPhoto" />指定カテゴリの画像取得</label>
  3. <label><input type="radio" name="select_func" value="getPhotoByPeriod" />期間を指定して画像を取得</label>
  4.  
  5. <div id="getMemberPhoto">
  6.     <select class="params" name="member_id">
  7.         <option value="1">だれそれ</option>
  8.         ...
  9.     </select>
  10. </div>
  11.  
  12. <div id="getCategoryPhoto">
  13. ...
  14. </div>
  15.  
  16. <div id="getPhotoByPeriod">
  17. ...
  18. </div>
  19.  
  20. <input type="button" value="画像取得" onclick="getPhotos" />

と、こんな感じで使えるよね?ということで(引数、微妙にも違ってないし)。
要jQueryなコードで、且つ実際に組んだコードではないので(爆)←古い、動かない可能性大ですが何かの参考にでもなれば。

ってならんな、こんなん。どこで使うねん。

12月24日 

javascript

javascriptのmatchで変数を抜き出す

文字列の中からパラメータを抜き出したいとき、

JAVASCRIPT:
  1. var hoge = "/member_id/29/".match(\/member_id\/(\d)\//);
  2. if (hoge != -1) {
  3.     var member_id = Regexp.$1;
  4. }

みたいな書き方が一般的だと思うんだけど、

JAVASCRIPT:
  1. var member_id = "/member_id/29/".match(\/member_id\/(\d)\//)[1];
  2. if (member_id != null) {
  3.     ...
  4. }

みたいな書き方も出来るよ、という覚え書き。
もち、複数の値を抽出したいときは前者の手法を使えば良し、ということで。

次の記事 »