「jQuery」カテゴリーアーカイブ

iPadで加速度センサー / jQueryゼロから

iPad/iPhoneでiOS4.2以降はブラウザでも加速度センサーの値がとれるのでちょっとテストした時のをまとめます。
javascriptではdevicemotionイベントで取れます。

1
2
3
4
5
6
7
8
$(window).bind('devicemotion', function(e){
    // 加速度
    var a = e.originalEvent.acceleration;
    // 重力加速度
    var g = e.originalEvent.accelerationIncludingGravity;
    // 回転加速度
    var r = e.originalEvent.rotationRate;
}

重力加速度で画面を傾けるとコリント的な動きさせる場合は、下記の感じ。

1
2
3
4
5
6
$(window).bind('devicemotion', function(e){
    // left, top が対象の左上の x, y 座標
    var g = e.originalEvent.accelerationIncludingGravity;
    left += g.x;
    top -= g.y;
}

これだけだとよくあるので、画面を傾けると回転しちゃう場合も考慮に入れてみます。
※画面ロックしなかった時にぐるっと回っちゃうので…
画面の回転はwindow.orientationから0, 90, 180, -90で取れます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(window).bind('devicemotion', function(e){
    var g = e.originalEvent.accelerationIncludingGravity;
    var dx, dy = 0;
    if (window.orientation == 0) {
        dx = g.x;
        dy = -g.y;
    } else if (window.orientation == 90) {
        dx = -g.y;
        dy = -g.x;
    } else if (window.orientation == 180) {
        dx = -g.x;
        dy = g.y;
    } else {
        dx = g.y;
        dy = g.x;
    }
    left += dx;
    top += dy;
}

あとは画面からはみ出ないようにとかする場合は orientationchange イベントで調整できます。
例えば canvas を画面いっぱいにした場合は、canvasサイズも変更しつつ画面の右下の最大値を調整します。

1
2
3
4
5
6
7
$(window).bind('orientationchange', function(e){
// size は描画するオブジェクトの大きさ
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    maxX = canvas.width - size;
    maxY = canvas.height - size;
});

まあ、回転に対応するケースはなさそうだけど…

サンプル ※iPadでみてね

iPadでスワイプ / jQueryゼロから

ちょっと特殊だけど、iPadでスワイプ処理を自分で書くことがあったので。
たぶんGalaxyでもあんまり変わらないはず。

タッチイベントは touchstart, touchend, touchmove で拾えます。
touchmove の際に event.touches に座標が入ってます。
配列なのは5つまでデータが入っているから。
今回は、ただのスワイプなので touches[0] だけ使います。

とりあえず座標を拾ってみます。

1
2
3
// touchmove で座標を拾う
X = event.touches[0].pageX;
Y = event.touches[0].pageY;

サンプル ※iPadで見てください

touches には pageX, pageY, screenX, screenY, clientX, clientY があり、ページやスクリーンの相対座標として取得できます。
画面を固定する場合は特に変わりはないですが、スクロールする場合は使い分けが必要です。
※pageX, pageYはスクロールする場合は指に追従してページも移動するので

とりあえず、touchstart と touchend の時の座標の差でスワイプを判定してみます。
X方向に100px動いたらスワイプします。※値は適当です

1
2
3
4
5
6
// touchendで判定
if (startX - endX > 100) {
// prev
} else if (endX - startX > 100) {
// next
}

サンプル

これでもスワイプは出来るのですが、いくつか問題があるのでもう少し調整してみます。
・縦(斜め)にスワイプしても横移動が100px以上ならスワイプするのをやめる
→ touchstart と touchend の確度を小さくする(2点を結ぶ直線の傾きが0.5以下としてみる)
・速度が遅くてもスワイプするのをやめる
→ 0.7秒以内のみスワイプとする
・iPadだと画面がズレる(指に追従する)のをやめる
→ よく使われている方法を参考に preventDefault でブラウザの挙動を無視する

サンプル

画像をプリロード / jQueryゼロから

画像のプリロードは前にもやったんだけど少し小技をはさんでみた。
プリロードしたって間に合わん時は間に合わんので、せめて見栄えが悪くないようにしようかってはなしです。

下記の感じで画像のプリロード時に読み込み完了後の処理を指定しちゃいます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var imagePath = '/images/';
var preloadImages = [
    'ooo.jpg',
    'xxx.jpg',
    '***.jpg'
];
var images = [];

(function($){
    for (var i = 0; i < preloadImages.length; i++) {
        var image = new Image;
        image.src = imagePath + preloadImages[i];
        images.push($(image).hide());
        (function(i){
            image.onload = function(){
                images[i].fadeIn();
            };
        })(i);
    }
})(jQuery);

読み込みが間に合わなかった時のために画像は hide() で非表示にして、image.onload で読み込み完了時の動作を指定しました。
※今回だとfadeInさせてます

サンプル

jQueryゼロから / ナビ付きスライドショー

前回のスライドショーによくあるナビつけてみることに。
任意の写真をクリックで選べるようにします。

ナビをクリックすると自動再生されてるアニメーション(フェードイン・フェードアウト)を停止して、指定のスライドを表示、しばらく放置すると自動再生再開するようにします。
アニメーションは setInterval で再生しているので、clearInterval にて停止するだけ。アニメーション再開は一定時間操作しない時間帯を持ちたいので setTimeout で待機するようにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var interval;
// スライド再生
function startSlide(wait){
    wait = wait | 0;
    var intervalTime = 3000;
    setTimeout(function(){
        interval = setInterval(function(){
            // アニメーション処理
        }, intervalTime);
    }, wait);
}

// スライド停止
function stopSlide(){
    clearInterval(interval);
}

ナビのロールオーバーとかはJavaScriptのイベントじゃなく、CSSで設定するようにしました。
あとは意外にそんな前のと変わらんので、jQueryのプラグインにして、$(セレクタ).slide(オプション) でスライドショーになるようにしてみた。
サンプル

ナビ付きスライドショー – jsdo.it – share JavaScript, HTML5 and CSS

JavaScript で cron ちっくに指定時間で実行

毎時0分に実行、みたいな処理したいなと思って調べた。
jsCron というのがよく使われているみたい。
cronちっくに 0 * * * * Function() のように指定するとその時間に実行する、と。
jsCron, portando Cron a Javascript | aNieto2K

ソース見てみると setInterval で現在時刻をチェックして、指定時間と一致するなら実行、という感じ。
定期的に時刻指定で実行するときは参考に。

応用してこんなのも。
サンプル (HTML5 audioでチャイム鳴らす)

下記は簡単なサンプル。(00秒に赤い★が表示されるだけ)
一秒以下の誤差はざっくりと無視してます。

JavaScriptで毎時実行 – jsdo.it – share JavaScript, HTML5 and CSS

続・jQueryの書き方

ノンプログラマに jQuery のおまじない部分でつまずくと言われたのと、自分も少し使い分けが整理できてきたのでまとめてみる。意外とルーブとか条件判定は悩まんけど、その前後にあるごにょごにょした部分がひかかるのだとか。

誤解を恐れずにまとめると JavaScript はグローバル変数を汚染しやすく、コンフリクトしたら嫌なので回避しようぜってコトよね。
んで、その書き方がいくつかありますよと。

<head> タグ内でサクッと済ませたい時

1
2
3
jQuery(function($){
    // $('#id').click() とかココに書いてく…
});

Onload前に実行したい場合にこう書いてます。
<head> タグ内だけじゃなく別ファイルでも使えるけど、ちょっと試したい時とか、簡単な処理の時によく使うかな。

$(function(){…}); って書き方もあるけど、古くは prototype.js と競合したり、気が付けばWordPressのデフォルトで呼ばれる jQuery が noConfrict になってて使えなかったりするので、こう書くようにしてます。
また、noConfrict をあえて宣言して $ を使わず、$j = jQuery; として置き換えたり、潔く全て jQuery(…) で書いてもいいんだけど、$ で書くのが手軽だし最初にこう書くだけで、その中ではいつも通りというのが楽なんよね。

先読みするファイル内で jQuery 使いたい時

1
2
3
(function($){
    // $('#id').click() とかココに書いてく…
})(jQuery);

自前の関数とかでも jQuery 使いたい時とか。別ファイルだと読み込みのタイミングで評価されるので、実行部分よりも関数とかあらかじめ指定する時によく使うかな。
(function(){})(); って書き方は function ooo(){…} 的な指定と ooo(); って実行をまとめて書いてるだけです。これに引数として jQuery を渡して、内側では $ で記述できるようにしてます。

あ、でも、関数定義して他の js ファイルからもこれを利用したい場合は、そのままでは使えません。その場合は、下記のようにしてあえてグローバルにしたりします。

1
2
3
4
5
6
(function($){
    function ooo(){
        ...
    }
    window.ooo = ooo;
})(jQuery);

※蛇足かも…

jQuery のプラグイン

1
2
3
jQuery.fn.ooo = function(){
...
};

これプラグイン書かないと使わないので、なんでこんな書き方なんだという説明だけしとく。
jQuery も当たり前にコンフリクト対策してあって、グローバル変数は jQuery と $ しか使わないように工夫されてます。プラグインであってもこのルールに乗っかれるようになってて、jQuery.fn.ooo のように指定すれば、$(‘#id’).ooo() といった統一の書き方になるように作られてます。

たまにコンフリクト考えてなくて $.fn.ooo から書かれてるプラグインあったりするので、その場合は2番目の方法でプラグイン指定を囲んでやると良いす。一行目に (function($){ 、最後の行に })(jQuery); って書けばうまく行く事もあれば、行かない事もあるよ。

あ、ちなみに JavaScript では下記2つは大体同じ意味です。
※厳密には評価されるタイミングが違う

1
2
3
4
5
6
7
function ooo() {
...
}

var ooo = function(){
...
};

うーん、あんまりまとまってないかな?
んでも、書き方はイロイロあるけど簡潔に書かれてるものが好まれてるだけと思う。

Transform / 回転・拡大縮小

2012.05.31 追記
ブラウザ判定がうまく動かなくなってたので、transform が使用できるかで判定するように変更しました。
機能の判定はブラウザのバージョンアップで変わってくので別の用途には使うべきじゃないね…

CSS3どころかCSSも普段あまりいじらないけど、回転・拡大縮小できる transform があるというコトなのでやってみる。
んでも、まだまだブラウザごとに実装が異なるらしく、jquery-css-transform.jsjquery-animate-css-rotate-scale.js っていう jQuery プラグイン使いましょうってのが多かったので、これを参考にしてみた。

CSS3では、transform: rotate(30deg) で要素を時計回りに30度回転、transform: scale(1.5) で要素を1.5倍とかいった指定が可能。んで、これが今んとこブラウザによって違ってて Chrome/Safari なら -webkit-transform、Firefox なら -moz-transform という具合。

これを jQuery で設定するには下記の感じ。JavaScript と CSS でパラメータ名が若干違うのに注意。

1
2
3
4
5
6
7
8
// Chrome / Safari (webkit) の場合
$('#target').css({ WebkitTransform: 'rotate(30deg) scale(1.5)' });
// firefox の場合
$('#target').css({ MozTransform: 'rotate(30deg) scale(1.5)' });
// Opera の場合
$('#target').css({ OTransform: 'rotate(30deg) scale(1.5)' });
// IE9 の場合
$('#target').css({ msTransform: 'rotate(30deg) scale(1.5)' });

rotate だけ、scale だけでもよいす。座標移動の translate もあるけど割愛。
これをブラウザ判定して使い分けます。jquery-css-transform.js だと transform, WebkitTransform, MozTransform,… と順にプロパティがあるかループで調べて判定してます。正式に tranform に対応したらそちらで処理するようにって事だと思う。(※2012.05.31追記 jquery-css-transform.jsのやり方がベンダープレフィックスが取れた時にも対応できるのでよりイイです)

パラメータの指定方法見ると、値に数値以外の文字もあるので jQuery の animate メソッドが使えないんよね。それで、jquery-animate-css-rotate-scale.js も別途用意されてる模様。

んで、試しに画像に適用したのが下記サンプルです。一応、プラグイン使わずにやってみた。
サンプル

もやもや – jsdo.it – share JavaScript, HTML5 and CSS

jQueryゼロから / slideToggle

クリックで開いたり閉じたりするのをサクっとつくるのに slideToggle 使うと便利。
slideUp, slideDown 組み合わせてもいいんだけど、こっちのが楽ね。

1
2
<span id="slide">ここをクリック</span>
<p id="target">なんか表示</p>

slideToggle にも引数でアニメーションの速度指定できます。
ただ、slideUp, slideDown の速度を使い分けるとかは出来ないんかな。

1
2
3
$('#slide').click(function(){
    $('#target').slideToggle('slow');
});

サンプル

jQuery Toggle Slide – jsdo.it – share JavaScript, HTML5 and CSS

jQueryゼロから / BlackOutふたたび

前回のがウィンドウサイズに追従しなくて恥ずかしい感じだったので、やり直し。WordPressのプラグインアップデートの画面がそんなんだったので、見て真似しました。(Thickbox使った方が早いって話だな)

まずはブラックアウト用に <div id=”layer”> ってのを用意、画面を覆うようにCSS設定します。
前回との主な違いは position: fixed; にして、width & height を100%にしてます。

1
2
3
4
5
6
7
8
9
10
11
12
#layer {
    position: fixed;
    z-index: 100000;
    background: #000000;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    filter: alpha(opacity=0);
    opacity: 0.0;
    display: none;
}

あとは前回同様に <a class=”blackout”> をクリックで先の <div id=”layer”> を表示させます。(classだと画面内に複数置けるので)
CSSで width, height を 100% にしてるので、前みたいにいちいち Window サイズ拾わないので楽です。実質 show, hide と fadeIn, fadeOut だけ。

1
2
3
4
5
6
7
8
9
10
11
jQuery(function($){
    $('a.blackout').click(function(){
        $('#layer').show()
                   .fadeTo('slow', 0.8);
    });
    $('#layer').click(function(){
        $(this).fadeTo('fast', 0, function(){
            $(this).hide();
        });
    });
});

サンプル

blackout – jsdo.it – share JavaScript, HTML5 and CSS

jQuery Mobile / とりあえずページ作ってみる

あれこれ見つつまずは基本的なところからやってみる。
チュートリアルとしてこちら参考にしつつ。
jQuery Mobile [基礎編]

詳しくはリファレンスを日本語化されているこちらで。
jQuery Mobile リファレンス

あとは、こちらにリンク集がよくまとまってます。
jQuery Mobile が必須スキルになる!と思うのでこれから勉強する際に参考になる記事まとめ | バシャログ。

jQuery Mobileって名前がついてるけど、どちらかと言うとHTMLの記述メインかな。まだ深くはさわってないけど。

まずは、その前にHTML5で基本的なところを。
あと jQuery や jQuery Mobile を読み込みます。
※ 下記は jQuery のCDN使ってます

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>jQuery Mobile</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
    </head>
    <body>
        <!-- ここになんか書きます -->
    </body>
</html>

jQuery Mobie では、スマホでよく使う機能がテンプレの様にまとめられてます。
ヘッダ、フッタ、メインのコンテンツ部分などは以下の感じ。
※<body> タグ内に書きます。

1
2
3
4
5
6
7
8
9
10
11
<div data-role="page">
    <div data-role="header">
        <h1>ヘッダ</h1>
    </div>
    <div data-role="content">
        コンテンツ
    </div>
    <div data-role="footer">
        フッタ
    </div>
</div>

基本は<div>タグで data-role を指定するだけです。
<div class=”header”>みたいなマークアップとおんなじよね。
また、一画面は <div data-role=”page”> でくくる必要があります。
※ひとつのファイルに複数画面書けるので

これだけでもそれっぽいデザインになりますが、ボタンを追加してみます。
今回はボタン風のリンクを使用して、ダイアログを開きます。

1
<a href="dialog.html" data-role="button" data-rel="dialog" data-transition="pop">OPEN</a>

data-role=”button” でボタンのようなスタイルを指定、data-rel=”dialog” でJavaScript の alert 的なダイアログになります。data-transition=”pop” でアニメーションの指定をポップアップにします。
※アニメーションは他にも slide などイロイロ指定できます

ダイアログも同様に別ファイルで用意してみます。
※同一のファイルに設定することも出来ます

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title> Dialog | jQuery Mobile</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
    </head>
    <body>
        <div data-role="page" id="dialog">
            <div data-role="header">
                <h1>Dialog</h1>
            </div>
            <div data-role="content">
                <p>Dialog</p>
                <a href="index.html" data-role="button" data-rel="back">Back</a>
            </div>
        </div>
    </body>
</html>

data-rel=”back” を指定して、戻るボタンもつくっときます。

だいたいこんな感じで、基本的なページは作れます。普通のページなら、指定されたタグを書いてくだけ。

サンプル (ダイアログは別ファイル)
※スマホで見るか、Chrome or Safari で見て下さい

デモ (一ファイルに複数ページで記述)