前回、ローカルアプリケーションキャッシュ機能を使って、Xmarksに替わる、オレ専用のブックマークWebアプリを作る - ふにゃるんを作った訳ですね。
それから更に調子に乗って、オレオレ専用のはてぶWebアプリを作ってみました。
何で作ろうと思ったか
iPodというかiPhoneには、元々はてぶアプリがあるんですが、出来るのはブックマークかWebブラウジングのみ。
iPodのはてぶアプリで、ブックマークしようとすると、以下の問題に突き当たります。
- 無線LANといえど、パソコンでWebブラウズする方が視認性が良いし速い。
(現在の所、iPodのWebブラウズは補助的に使っている状態。未だにメインはパソコンなんですね) - ブックマークする際、タグをiPodで打ち込むのは、恐ろしい苦行なり。
(ブラインドタッチに慣れているので、思考と入力が一致しないのは、恐ろしく不便) - パソコンでは、オレ専用のブックマークアプリを使って楽しているから、そっちで使いたい。
(P4Dで、はてレジ(はてなブックマークを登録するツール)を作ってみました - ふにゃるんのことです) - iPhoneなら常時ネット接続だが、iPodなので、常時ネット接続じゃないので、オフライン重視じゃないと困る。
(オフラインサポートしていないニュース系アプリは即行削除行きだったり。:-P)
以上の理由と、手にした技術で遊んでみたいという強い欲求から、オレオレ専用な はてぶWebアプリを作ってみた次第です。
参考にしたWebサイト
今回参考にしたWebサイトは、以下の通りです。
- jQuery 日本語リファレンス
http://semooh.jp/jquery/ - jQuery Mobile | jQuery Mobile
http://jquerymobile.com/ - [jQuery Mobile] - すにぺっと
http://d.hatena.ne.jp/sy-2010/searchdiary?word=%2A%5BjQuery%20Mobile%5D - Web Storage の残容量を調べてみた - latest log
http://d.hatena.ne.jp/uupaa/20100106/1262781846 - localStorageの挙動と簡単なラッパー - but hopeful
http://d.hatena.ne.jp/Jxck/20100821/1282412125 - JavaScript: 外部RSS読み込み by “Google Ajax Feeds API” | t.p.fields - web+tech info
http://tpfields.xrea.jp/javascript/load-external-rss-by-javascript-google-ajax-feeds-api.html - JavaScriptでmailtoを起動する場合 « for WEB屋
http://www.4web8.com/224.html - (v)sprintf | jQuery Plugins
http://plugins.jquery.com/project/printf
使っている技術
参考にしたWebサイトでもわかる通り、今回使用した技術は、大体こんな感じです。
- jQuery Mobile
- 前回は jQtouchでしたが、今回はjQuery Mobileです。
採用に特に意味は無く、一応本命と言われているので 試してみたくなっただけです。 - Google Ajax Feeds API
- 今回、外部ドメインのRSSデータを取得する必要がありまして、普通はCGIか何か置いて、CGIから外部ドメインのRSSデータを取得したりするのがセオリーっぽかったんですが。
まぁ、これでも良いかな。と。 - HTML5のローカルストレージ
- ローカルに永続的にデータを格納できる技術として、ローカルストレージ技術とSQLを用いた技術があるようなんですが、今回は楽っぽい(キーバリューでOKなんですもん)ローカルストレージにしました。
ソースコード
てけとーではありますが、ソースコードを晒します。
<!DOCTYPE html> <html manifest="test_hatebu.manifest"> <meta charset="UTF-8" /> <title>はてぶホットエントリをチェキ</title> <link rel="stylesheet" href="lib/jquery.mobile-1.0a3.min.css" /> <script src="lib/jquery-1.5.min.js"></script> <script src="lib/js_sprintf.js"></script> <script src="https://www.google.com/jsapi?key=$ここに取得したキーを入れて" type="text/javascript"></script> <script type="text/javascript" charset="utf-8"> function make_entry(feed){ console.log("make_entry=%d", feed.entries.length); var ary = jQuery.map(feed.entries, function(n, i){ var s = $.sprintf( "<div class='ui-bar ui-bar-b'> \ %(no)d: %(title)s \ </div> \ <div> \ <div data-role='controlgroup' data-inline='true' align='right' data-type='horizontal'> \ <input type='checkbox' name='chk' id='chk-%(no)d' value='%(url)s'/> \ <label for='chk-%(no)d' data-icon='start'>後で</label> \ <span> </span> \ <a href='%(url)s' data-role='button' data-icon='arrow-r' target='_blank'>URL</a> \ </div> \ <p>%(content)s</p> \ </div>", { no: i+1, url: n.link, title: n.title, content: n.contentSnippet, detail: n.content }); return s; }); $("#rss").append(ary.join()); } function load_entry() { console.log("load_entry"); var feed_url = "http://b.hatena.ne.jp/hotentry.rss"; var feed_content = null; try{ console.log("no local storage[%s]", feed_url); var feed = new google.feeds.Feed(feed_url); feed.setNumEntries(100) feed.load(function(result) { feed_content = JSON.stringify(result.feed); localStorage[feed_url] = feed_content; }); console.log("set local storage!!"); }catch(e){ console.log("sorry fail fetch:" + feed_url); } if(feed_content == null){ feed_content = localStorage[feed_url]; } var feed = JSON.parse(feed_content); make_entry(feed); } try{ google.load("feeds", "1"); }catch(e){ console.log("fail google.load"); } //google.setOnLoadCallback(load_entry); </script> <script type="text/javascript" charset="utf-8"> console.log("custom script code!!"); // 設定の為の初期化 $(document).bind("mobileinit", function(){ console.log("mobileinit"); }); // 普通の初期化 $(function(){ console.log("function!!"); var clickTrigger = ($.support.touch)? "tap": "click"; $("#call-mail").bind(clickTrigger, function(){ //$("[name='select']:checked").each(function(){ var chks = $(":checked").map(function(){ return this.value; }).get(); //alert("checkbox:" + chks.join(",")); if(chks.length > 0){ s = "subject=" + "after_check!!" + "&body=" + chks.join("\n"); location.href = "mailto:$メアドを入れて?" + encodeURI(s); } return false; }); }); $('#main').live('pagebeforecreate',function(event){ console.log("pagebeforecreate"); // ページを作成する前に、はてぶエントリーを生成する // でないと、スマートフォンな外観にならないから load_entry(); }); $('#main').live('pagecreate',function(event){ console.log("pagecreate"); }); console.log("end of script tag"); </script> <script src="lib/jquery.mobile-1.0a3.min.js"></script> </head> <body> <!-- Start of first page --> <div data-role="page" id="main"> <div data-role="header" data-theme='d'> <h1>はてぶホットエントリ</h1> <a id="call-mail" href="#" class='ui-btn-right'>to メール</a> </div> <div data-role="content"> <div id="rss"></div> </div> <div data-role="footer" data-theme='a' align='center'> <span>end of document </span> <a id="call-mail" href="#">to メール</a> </div> </div> </body> </html>
あと、ローカルWeb化する為に、test_hatebu.manifest ファイルを同じフォルダに突っ込んでおきましょう。
CACHE MANIFEST # rev1 CACHE: lib/jquery.mobile-1.0a3.min.css lib/jquery.mobile-1.0a3.min.js lib/jquery-1.5.min.js lib/js_sprintf.js lib/images/ajax-loader.png lib/images/form-check-off.png lib/images/form-check-on.png lib/images/form-radio-off.png lib/images/form-radio-on.png lib/images/icon-search-black.png lib/images/icons-18-black.png lib/images/icons-18-white.png lib/images/icons-36-black.png lib/images/icons-36-white.png
なお、lib/js_sprintf.js ファイルは、jQuery pluginの http://plugins.jquery.com/project/printf からゲットしたコードを置いています。
動かしてみる
WWWサーバーに適当に放り込んだファイルを、iPodのSafariから参照すると、以下の画面が出て来ます。
(機内モードで、ちゃんと動いているのが判りますか?)
基本的に、「後で」にチェックを付けまくって、ヘッダもしくはフッタにある、「to メール」ボタンを押すと、チェックを付けたURLがメールの本文に適用される。
といった流れです。
一応オマケとして、「URL」ボタンを押すと、はてぶエントリのWebページに飛んでいきます。
例えば、2つほど、エントリに対して「後で」をチェックします。
ここで、「to メール」ボタンを押すと、メーラーが起動して、チェックしたURLが本文に適用されます。
後は、メールするだけです。
簡単ですね。
ちなみに、1回目の読み込みで、エントリのWeb作成に反映せず、2回目以降で成功したりするバグを抱えています。
が、とりあえず動いたので晒すという暴虐。
最後に
全体的に文字がバカでか過ぎるので、もちっとコンパクトにしたいなぁ。と思っています。特に、「後で」「URL」ボタンのデカさと言ったら…。ふぅ。
しかし、今回で2つですが、テキトーでも、それらしくアプリケーションのように振舞うWebソフトが出来るなんて、HTML5って便利な技術ですね。
ここまで便利に動くとなると、いわゆるガラケーと呼ばれる既存の携帯も、HTML5をサポートすれば良いのに。と、思ってしまいますね。
Flash Liteがあるので、もっと高度な遊びが出来るのは判りますが、HTML5は更に技術の敷居が低いので、開発者の裾野が広がると思うんですがねぇ。
(ハードをスマートフォン化するより、手っ取り早いと思うんだけどなぁ)