2011/09/17

HTML5のSQL APIを試してみた

chrome が HTML5 の SQL DataBase API を実装していると言うので試してみた。

  • SQL Database APIの仕様はこちら
    http://www.w3.org/TR/webdatabase/

あれれ、仕様策定中止になってる..
SQliteなのがまずいのか?

まあそれはそれとして試してみよう。

単純な key/value のテーブルを作って保存/参照をしてみる。

  • test.html:
<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <script src="Persistent.js"></script> <script> function save() { var key = document.form1.key.value; var val = document.form1.value.value; Persistent.put(key, val); } function load() { var key = document.form2.key.value; Persistent.get(key, function(val){ document.form2.value.value = val; }); } </script> </head> <body> <button type="button" onclick="Persistent.init()">初期化</button> <button type="button" onclick="Persistent.dispose()">破棄</button> <hr/> <form action="" name="form1"> Key:<input name="key" value="" /> Value:<input name="value" value="" /> <button type="button" onclick="save()">保存</button> </form> <hr/> <form action="" name="form2"> Key:<input name="key" value="" /> Value:<input name="value" value="" readonly="readonly"/> <button type="button" onclick="load()">読込</button> </form> <hr/> </body> </html>

  • Persistent.js:
function Persistent(){} Persistent.DB_NAME = "Persistent"; Persistent.DB_VER = "1.0"; Persistent.DB_SIZE = 8192; Persistent.SQL_CREATE = "CREATE TABLE persistents (key TEXT PRIMARY KEY, value TEXT)"; Persistent.SQL_DROP = "DROP TABLE persistents"; Persistent.SQL_SELECT = "SELECT * FROM persistents WHERE key=?"; Persistent.SQL_DELETE = "DELETE FROM persistents WHERE key=?"; Persistent.SQL_REPLACE= "REPLACE INTO persistents VALUES(?,?)"; Persistent.getDatabase = function(sync) { if (sync) { // ワーカー内でしか使えないって ショボーン(´・ω・`) return openDatabaseSync( Persistent.DB_NAME, Persistent.DB_VER, Persistent.DB_NAME,Persistent.DB_SIZE ); } else { return openDatabase( Persistent.DB_NAME, Persistent.DB_VER, Persistent.DB_NAME,Persistent.DB_SIZE ); } } Persistent.init = function() { var db = Persistent.getDatabase(false); db.transaction(function(tx){ tx.executeSql(Persistent.SQL_CREATE, [], Persistent.onNop, Persistent.onError); }); } Persistent.dispose = function() { var db = Persistent.getDatabase(false); db.transaction(function(tx){ tx.executeSql(Persistent.SQL_DROP, [], Persistent.onNop, Persistent.onError); }); } Persistent.put = function(key, value) { var db = Persistent.getDatabase(false); db.transaction(function(tx){ tx.executeSql(Persistent.SQL_REPLACE, [key, JSON.stringify(value)], Persistent.onNop, Persistent.onError); }); } Persistent.remove = function(key) { var db = Persistent.getDatabase(false); db.transaction(function(tx){ tx.executeSql(Persistent.SQL_DELETE, [key], Persistent.onNop, Persistent.onError); }); } Persistent.get = function(key, callback) { var db = Persistent.getDatabase(false); db.readTransaction(function(tx){ tx.executeSql(Persistent.SQL_SELECT, [key], function(tx,rs){ if (rs.rows.length >= 1) { callback(JSON.parse(rs.rows.item(0).value)); } else { callback(null); } }, Persistent.onError); }); } Persistent.onNop = function(tx) { // nop. } Persistent.onError = function(tx,err) { alert(err.mesage); }

最初にに「初期化」でテーブルを作成してkey/valueを「保存」。

ブラウザを再起動して「読込」。

ちゃんと永続化できている。

疑問点:

  • トランザクションの開始が非同期。
  • SQLの結果処理も全て非同期。
  • 結果処理を非同期させないopenDatabaseSync()が使えない
    以下のサイトによるとワーカーでなら使えるらしい。
    http://d.hatena.ne.jp/onozaty/20110505/p1
正直かなり使いづらい。
SQLがそのまま使えるだけに残念な感じ。

2011/09/08

Google mapsでカスタムの吹き出し

(※画像使わずJS+CSSだけでマンガ風吹き出しのサンプル書きました →こちら)

スマホで Google maps api を使っていると標準の吹き出し(InfoWindow)が でかくて邪魔だ。

オプションで小さく出来るだろうと思って探したのだが InfoWindow にはそんなオプションは無い。

でも、標準以外の吹き出しなんてどこかで見掛けた気がするし 出来ないわけ無いと思って色々調べてやっと分かった。

Balloon をいじるのでは無くカスタム オーバーレイを使うらしい。

  • カスタム オーバーレイのAPIドキュメント
    http://code.google.com/intl/ja/apis/maps/documentation/javascript/overlays.html#CustomOverlays
  • 吹き出しのサンプル
    http://gmaps-samples-v3.googlecode.com/svn/trunk/infowindow_custom/
こいつを改造して自前の吹き出しを作ってみた。

因みにサンプルには無い吹き出しの影だが以下のサイトで作れる。 アイコンをUploadすると Google と同じ角度の影を生成してくれる。大変助かった。

  • Google map 用のアイコンの影を作ってくれるサイト
    http://www.powerhut.co.uk/googlemaps/custom_markers.php

2011/08/31

jQTouchとjQueryMobile

最近、スマホ向けWebアプリを作っている。

スマホ向けWebアプリのフレームワークとして jQTouchとjQueryMobile が有るのだがどちらを使うか悩ましいところ。

両方、使ってみたので所感をまとめてみる。

* jQTouch

  • 良い所
    • 安定している。
    • jQueryMobileよりは軽い
  • 悪い所
    • 開発が止まっている。(*1)
    • 機能が足りない。
    • ドキュメントが無い。
    • Android/2.1でこけた。
(*1)jQTouch は sencha.com の SenchaTouch に吸収されているようで 基本的にやる気が無いらしい。 SenchaTouch は商用/GPL3ライセンスの選択。

* jQueryMobile

  • 良い所
    • jQuery の正式モジュール
    • 機能は大体揃ってる。
    • 対応機種が多い。
    • 日本語のドキュメントが有る。
  • 悪い所
    • まだβ版でバグも多い。
    • 重い。

結局、jQueryMobile を選んだ。
ロードマップが不明なのが不安なのだが jQTouch には将来性はまったく無さそうだし、 使うなら SenchaTouch を GPL3 で使うほうがよさげ。

参考URL:

  • jQueryMobail: http://jquerymobile.com/
  • JqTouch: http://jqtouch.com/
  • Sencha: http://www.extjs.co.jp/
関連記事:

2011/08/07

HTML5で選択画像のサムネイル表示

<input type=file> で選択した画像を送信前にサムネイル表示 したかったで調べてみた。

結論から言うと HTML5 の FileAPI で出来る。

普通に input.value を取ろうとしてもローカルファイル名は セキュリティの関係で取れないので img.src=input.value は使えない。

HTML5 はローカルファイルを読みこんで URL として使える 形式にしてくれる。

コードはこれだけ

<html> <head> <script> function selectImage(_this, ev) { var reader = new FileReader(); reader.onload = function(e) { var img = document.getElementById("imageView"); img.src = reader.result; }; reader.readAsDataURL(_this.files[0]); } </script> </head> <body> <img id="imageView" src="dummy" width="200" /> <br/> <input type="file" name="file" onchange="selectImage(this,event);" /> </body> </html>

初期状態。

画像を選択。

サムネイルが表示される。

OKー。

関連記事:
CSS だけでサムネイル表示。


2011/01/16

IE8 の XMPタグ がバグってる。

友達からブログが崩れてると言われたので調べた。
どうも IE8 の時だけ XMPタグがおかしくなるらしい。

こんな感じのソースが
<xmp>
xmp test
xmp test
xmp test
</xmp>
こうなる。

通常の XMPタグは問題無かったので CSS との組み合わせと 睨んでいろいろいじってみたところ原因判明。
  • XMPタグの dsiplay のデフォルトが inline になっていた。
のである。
更に border の設定してたので余計にぐちゃぐちゃになってた。

CSS で以下の設定を追加して無事解決。 xmp { display: block; } 正しくはこんな感じ。

めでたし、めでたし。

2009/12/28

「未知の実行時エラーです」その2

またIEで「未知の実行時エラーです」を食らった。
結論から言うと form タグの内側で form を innerHTML に入れようとすると発生する。
普通に form を入れ子にする場合にはエラーにならない。

これを実行すると6行目で「未知の実行時エラーです」になる。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">

<script>
function init(){
var div = document.getElementById("test");
div.innerHTML = '<form><input name="test"/></form>';
}
</script>

<body onload="init();">

<form>
<div id="test"></div>
<form>
<input />
</form>
</form>
</body>

</html>


これを踏む事はあんまり無いかもしれないけど覚書。

しかし、エラーにする事自体は意味が分かるのに何で
「FORMは入れ子にできません。」
とエラーが出せないのかね。
それだけではまらずに済むのに。



2009/12/26

Firefoxのwindow.onerrorで文字化け

エラー処理がかったるいので window.onerror で一括処理しようとしたら文字化けした。


window.onerror = function(desc, url, line) {
alert(desc);
}
throw "テスト";


結果:

uncaught exception: ƹÈ


エスケープして文字コードを調べて見る。

window.onerror = function(desc, page, line, chr) {
alert(escape(desc));
}
throw "テスト";


結果:

uncaught%20exception%3A%20%C6%B9%C8


"テスト"のEUCコード 16進ダンプ。

00000000= a5c6 a5b9 a5c8


どうやら EUC(OSのデフォルト文字コード) に変換して下8bit に切ってるらしい..
完全に FireFox のバグでどうにもなりそうな気がしないので諦める。



2009/12/19

XMLHttpRequestとキャッシュ

XMLHttpRequestでキャッシュが効いてページを更新しても反映されなくなると言うのは良く聞くトラブルだ。
そんな感じの症状が出たので調整する事にした。

この辺を読むと相当グダグダな感じだが今回調べた最近のブラウザではまともになっていた。
http://www.semblog.org/msano/archives/000386.html

Firefox3.5 および IE7 の結果を整理すると

1. Expiers 又は max-age が指定されているページはリクエストしない。
2. 1.の状態だと F5(CTRL+F5も) でリロードしてもリクエストしない。
3. XMLHttpRequest に Cache-Control:no-cache ヘッダを指定すればリクエストする。

となった。

1. は期限切れとなればちゃんとリクエストするので通常のファイルと変わらない。
2. が通常のファイルと動作が異る。通常のファイルは Expiers を無視してリクエストし304になる。
これが混乱の元だと思われる。
なんせ、一旦キャッシュが効いてしまうと手動で回避する手段が無い(設定からキャッシュクリアと言うのは有る)

対策としては
1. サーバ側で Expiers をページ毎にきちっと制御する。
2. クライアント側で Cache-Control:no-cache を設定して毎回フルリロードする。
となる。できれば 1. の方が 304 が返せるので無駄が無い。
ユーザ操作でリロードとかしたい場合はクライアント側アプリで作り込むしかなさそ。

捕捉:
FirefoxはFireBugが入っていると js/css は無条件にリクエストに行ったりして挙動が違う。
こいつにだいぶ撹乱されたので動作確認する時はご注意。



プロフィール
20年勤めた会社がリーマンショックで消滅、紆余曲折を経て現在はフリーランスのSE。 失業をきっかけにこのブログを始める。

サイト内検索

登録
RSS/2.0

カテゴリ

最近の投稿【javascript】

リンク

アーカイブ