NUブログ 自作Webアプリで一発当てたいプログラマ

iPhoneのsafariについて

タグ:雑記, iPhone, safari

通常のsafariとの違いなど

対応していないもの

  • window.showModalDialog() or window.print()
  • Mouse-overイベント
  • hoverスタイル
  • ツールチップ
  • Javaアプレット
  • Flash
  • SVG
  • XSLT
  • プラグインのインストール
  • カスタムのx.509証明書
  • WML
  • ファイルのアップロードとダウンロード

HOME画面用favicon

DocumentRootに以下の画像を置く

apple-touch-icon.png

ページ毎に違うfaviconを使用したい場合、以下を<head>の中に書く

<link rel="apple-touch-icon" href="/customIcon.png"/>

サイズは57x57で作成する

ビューポートの指定

PCではウインドウのサイズを変えることができますが、iPhoneの場合は固定(980)されています。 ただし、<meta>タグで最適なサイズを指定することで、iPhoneはそれに合わせて表示してくれます。

<meta name="viewport" content="width=device-width; user-scalable=no;" />

device-width というのは、iPhoneが持っている固定値で、320です。
おそらく、今後もっと解像度の高い端末が出たときも、device-width を使用していれば、それぞれの端末のサイズを自動的に適用してくれるものと思われます。

iPhone の javascript でできること

基本的に PC版 safari でできることは大抵できるんですが、特に気になった部分をピックアップします。

コンソールにデバッグ出力ができる

設定 > Safari > デベロッパ > デバッグコンソールオン にすることで、safariのアドレスバーの下にデバッグコンソールが表示されます。
ここにログを表示したい場合は以下のメソッドを使用します。

console.log("通常のログの出力");
console.warn("警告を出力");
console.error("エラーメッセージを出力");
console.info("インフォメーション情報を出力");

データベースが使える

safari 3.1 から Gears のような SQLiteベースの javascript database が使用できるようになったそうですが、 iPhoneでも使用できます。

DB connect

var shortName = 'mydatabase';
var version = '1.0';
var displayName = 'My Important Database';
var maxSize = 65536; // in bytes
var mydb = openDatabase(shortName, version, displayName, maxSize);

これで mydb オブジェクトを使用することで、DBにアクセスできます。

SQLの実行

mydb.transaction(function(db) {
    db.executeSql('
        CREATE TABLE people(
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL DEFAULT "John Doe",
            shirt TEXT NOT NULL DEFAULT "Purple"
        );
    ', [], nullDataHandler, errorHandler);

    db.executeSql('insert into people (name, shirt) VALUES ("Joe", "Green");', []);
    db.executeSql('insert into people (name, shirt) VALUES ("Mark", "Blue");', []);
    db.executeSql('insert into people (name, shirt) VALUES ("Phil", "Orange");', []);
    db.executeSql('insert into people (name, shirt) VALUES ("jdoe", "Purple");', []);
});

結果セットの取得

mydb.transaction(function(transaction) {
    transaction.executeSql('select * from people', [], function(trs, results) {
        for (var i = 0; i < results.rows.length; i++) {
            var row = results.rows.item(i);
            console.log(row['name'] + ':' + row['shirt']);
        }
    });
});

マルチタッチの制御

タッチイベント

  • touchstart
  • touchend
  • touchmove
  • touchcancel

ジェスチャーイベント

  • gesturestart
  • gesturechange
  • gestureend

複数本の指を認識する

var touchStart = function(e) {
    console.log(e.touches.length);
}
document.body.addEventListener("touchstart", touchStart, false);

最高5本まで認識させることができました。でも実際には3本くらいまでしかまともに使えないっす。

複数本の指でタッチしたときの座標を取得する

var touchStart = function(e) {
    var pointers = ''; 
    for (var i=0; i<event.touches.length; i++) {
        pointers += (event.touches[i].pageX + ':' + event.touches[i].pageY + ' ');
    }   
    console.log(pointers);
}
document.body.addEventListener("touchstart", touchStart, false);

ピンチイン、ピンチアウト

var startScale;
var gestureStart = function(e) {
    startScale = e.scale;
}
var gestureChange = function(e) {
    e.preventDefault();
    e.target.style.webkitTransform = 'scale(' + e.scale  + startScale  + ');
}
document.body.addEventListener("gesturestart", gestureStart, false);
document.body.addEventListener("gesturechange", gestureChange, false);

回転

var startRotation;
var gestureStart = function(e) {
    startRotation = e.rotation;
}
var gestureChange = function(e) {
    e.preventDefault();
    e.target.style.webkitTransform = 'rotate(' + e.rotation + startRotation + 'deg)';
}
document.body.addEventListener("gesturestart", gestureStart, false);
document.body.addEventListener("gesturechange", gestureChange, false);

ピンチイン、ピンチアウト、回転を同時に設定

var startScale;
var startRotation;
var gestureStart = function(e) {
    startScale = e.scale;
    startRotation = e.rotation;
}
var gestureChange = function(e) {
    e.preventDefault();
    e.target.style.webkitTransform =
       'scale(' + e.scale  + startScale + ') rotate(' + e.rotation + startRotation + 'deg)';
}
document.body.addEventListener("gesturestart", gestureStart, false);
document.body.addEventListener("gesturechange", gestureChange, false);

全ての要素が拡大縮小/回転できてぐっちゃぐちゃになる。ちょっと面白いw