2011 10月 ITかあさん

ITかあさん

jQuery日本語リファレンスを使って実際にjQueryを書いてみよう

jQuery日本語リファレンス


jQuery日本語リファレンス
今回からjQuery日本語リファレンスを使って、実際にjQueryで処理を書いてみることにします。
jQuery日本語リファレンスはあなたが日本人でjQueryを使うなら、このサイトはおそらく最もお世話になるであろうサイトです。

jQueryAPIリストを大きく分ける

jQueryのAPIリストを見ると、関数のようなものが大量にあり、まず何からしていいのかが分かりません。そこでAPIリストを大きく分けてみることにします。

APIをざっくり分けるとこうなる

Selectors(要素の選択) #id、element、.class、*など。 $("#hoge").css("color", "red");
*idがhogeのテキストを赤くする
Attributes(属性) attr(name)、attr(properties)、attr(key,fn)、removeAttr(name) var img = $(“img”).attr(“src”);
*imgタグのsrcを取得しています
Traversing(要素を選択したり、孫ザをチェックしたり) css(name)、css(properties)、css(name, value) var img = $(“img”).attr(“src”);
*imgタグのsrcを取得しています
Manipulation(挿入) append(content)、appendTo(content)、prepend(content)、prependTo(content)
CSS(CSSの変更、見た目に関すること) append(content)、appendTo(content)、prepend(content)、prependTo(content) $("#hoge").css("color", "red");
*idがhogeのテキストを赤くする
Events(マウスやロードなどユーザーの動作に合わせて発動) ready(fn)、click()、blur()、focus()、load()、submit()、hover(over, out)、toggle()
Effects(エフェクト アニメーション効果など) show()、hide()、fadeIn()、fadeOut、animate()
*1Ajax(HTTP通信など) load()、jQuery.get()、jQuery.removeData(elem)

*1:個人的にはAPIのうち Ajaxについてはあまり高頻度に使ってはいませんがページを特定の場所に読み込んだり、JSON形式のデータの通信を行ったり出来ます。
使い方にもよりますが、RSSのパーツを読み込んだり、ブログパーツのような形で部分的にデータを読み込ませることが可能です。

jQueryの基本的な使い方

jQueryで何かしようと思った場合(普通のjavascriptでも)自分のやりたいことを日本語で書いて、それをAPIに置き換えればいいんです。

何をどうしたらどんな風にしたいかってね。

pタグをクリックしたらフェードアウトで消えていく処理をしたい

下記のように毎回表で置き換えると分かりやすいかもしれません。
『何を』はSelectors、『どうしたら』はEvents、『どんな風に』はEffectsといった具合に。
正確にはもっとたくさんあるんだけど、初級レベルならこれだけで何でも作れます。

何を(Selectors) どうしたら(Events) 何がSelectors どんな風に(Effects)
pタグを クリックしたら クリックされたpタグ自身が フェードアウトする
$(‘p’)*2 click(fn)fnとはfunctionのこと $(this)自分自身のこと fadeOut([speed], [callback])

*2$(‘p’):とはjQuery(‘p’)の省略系。
Selectorsなら、jQuery日本語リファレンス Selectorsの欄から自分のたりたいことにマッチしたAPIを探せばいいんです。ただそれだけ。

ではこれはどう書けばいいでしょうか

pをクリックしたらフェードアウトする
$(‘p’)(何を)をclick()(どうしたら)したら$(this)何が.fadeOut()(どうなる)

赤字の~したらはfunction(){}として置き換えられます。

先ほどの例をjQueryで書いてみよう

書き出しはこれ。ready(function(){この中に処理を書く})と、DOM要素全てが読み込まれてから処理が開始されるんでしたね。
もし、</body>の直前に書くことが可能でしたらそれでもかまいません。

jQuery書き出し

<script>
$(document).ready(function(){
});
</script>

クリックしたら、クリックされたほうの処理はclick()この括弧内に書いていきます

$(document).ready(function(){
$("p").click(function () {
$(this).fadeOut("slow");
}); });

どうですか?簡単でしょう?
慣れていないうちは、このfunction(){}を見ただけで難しく考えてしまいますが、(クリック)したらの『~したら』という接続的な役割をしているものと考えればさほと難しくありませんね。
クリックされた方自体の処理は、click()の中のfunction内に書いていけばいいのです。

基本的な処理の書き方は以上です。後はDOM要素をどのように選択するかさえ掴めれば、大抵の処理は可能になります。
と、いうわけで次回は様々なSelectorsの勉強をしていきたいと思います

GoogleMapsAPI で住所から座標を取得

深いことは気にせず、単純に日本語の住所から座標を取得してGoogleMapにアイコンを表示させる方法です。

日本語住所からマップとアイコンを表示させる

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>GoogleMapsAPI で住所から座標を取得</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=(key)&sensor=false"
type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(document).ready(function(){
var map;
var geocoder; if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
geocoder = new GClientGeocoder();
var address = '東京都新宿区歌舞伎町1-19';
//ここを変更 geocoder.getLatLng(address, moveTo);
map.addControl(new GLargeMapControl());
//マップのコントロール
}

function moveTo(latlng) {
if (latlng){
map.setCenter(latlng, 15);//ズーム map.clearOverlays();
var marker = new GMarker(latlng);
map.addOverlay(marker);
}else{
alert("住所から緯度経度に変換できません");
}
}

});
</script>
</head>
<body>
<div id="map_canvas" style="width: 400px; height: 400px"></div>
</body>

解説

マップの表示(Javascript)をどこで発動させるかは自分次第なのですが、私はjQueryを利用して、DOMの読み込み完了してから表示させるようにしました。
var address = ‘東京都新宿区歌舞伎町1-19’この部分を表示させたい住所に変更させるだけで完了です。
さらに吹き出しを表示させたい場合はこちらの記事が参考になります。
Geekなぺーじ:ふきだし内のメッセージに画像を入れる
吹き出し部分は通常のHTMLを入れることが可能なんですね。知りませんでした

bindModelを複数するときはrecursiveが大事

複数のbindModelをするときはrecursiveが大事

久々にCakephpの話題なのですが、複数bindModelしたい時はrecursiveが非常に大事というお話。

例:4つのテーブルを連携する

今回私は4つのテーブル(Model) を使いました。これだけ多数のModelを使うと、4つ全てが関連付け(foreignKey)されあっていることはないですわね。言い換えると、あるModelの中で別のModelを扱うということ。
例だと、最終行を見てもらった通りGroupShopが一番の親になるわけです。

各Modelの関係性

この関係性だと、GroupShop Prefectureこの2つが関係しあってないので、GroupShopに対してbindModelできません。どう頑張っても。
そこで、唯一関係しあっているShopモデルと先にbindModelで別にbindしておく必要があります。

ShopとPrefecture 関連
ShopとGroupShopとGroup 関連
GroupShopとPrefecture 関連していない

下記はコントローラーの内容です。

$this->Shop->bindModel(
array(
'belongsTo'=>array(
'Prefecture'=>array(
'className'=>'Prefecture',
'conditions'=>'',
'order'=>'',
'foreignKey'=>'prefecture_id'
)
)
));


$this->GroupShop->bindModel(
array(
'belongsTo'=>array(
'Group'=>array(
'className'=>'Group',
'conditions'=>'',
'order'=>'',
'foreignKey'=>'group_id',
),
'Shop'=>array(
'className'=>'Shop',
'conditions'=>'',
'order'=>'',
'foreignKey'=>'Shop_id',
)
)
));

$con = array(
'conditions'=>array('group_id'=>$id) ); $groups = $this->GroupShop->find('all',$con);

上記の書き方ではあるものが抜けているので 最初にbindeModelしたPrefectureのデータまで拾うことは出来ません。
なお、Modelで結合させても結果は同じです。忘れがちなあるものが無いのです。

bindModelはデフォルトでは第一階層までしか見ない

Cakephpは特に指定しなければ結合してあるModelの第一階層、つまり自分が直接結合しているModelしか読みに行かず、孫(ここではShopと関連付けされているPrefecture)
を一切見てくれません。そこで、さらに下の階層まで読みにいかせる場合はrecursiveを指定してあげる必要があります。

recursiveとは深度のことです。

findするModelにrecursiveを指定する

今回、自分は直接結合していない孫のModelの内容まで見る場合は’recursive’ => 2にしてあげれば 孫まで読みに行くことが出来るようです。

$con = array(
'conditions'=>array('group_id'=>$id),
'recursive' => 2
); $groups = $this->GroupShop->find('all',$con);

単純なことのようで、知らないってことってあるんですね。
Cakephpの参考書にもrecursiveについては載っているのですが、深度ですよ~との説明しかなかったので、
今まで全く気にしていなかったのですが、今回のように自分が直接bindしていないModelを読みにいく場合は使えそうです。

3.7.8.6 recursive
なお、Cakephpのマニュアルにあるとおり、必要以上に設定すると処理が重たくなるので必要最低限にしましょうとのこと。

このまま見過ごしていたら、サブクエリで全部やるところでした。ヤレヤレ。

さあ!jQueryを使ってみよう

Google Libraries APIより、jQueryを読み込み

まずはjQueryの読み込みから。
下記URLにてGoogleAPIより最新版のjQueryをお借りすることが出来ます。
当然自分のサーバーに設置してあげる方が効率がいいわけですから、最終的には自分のサーバーへ置くのがいいでしょう。このコーナーのサンプルのjQueryは下記URLのものを利用しています。
http://code.google.com/intl/ja-JP/apis/libraries/devguide.html#jquery
なお、最新版以外も設置することが可能です。
view older versionsのリンクをクリックすると、バージョンが出てきますから、
https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js
数字を自分の好みのバージョンに書き換えることで 古いバージョンのjQueryを読み込むことが可能です。
当然古いバージョンのjQueryでは使えないメソッドもありますから注意が必要です。(メソッドが何かは後々やっていきますね)
Google Libraries API
人気Ajaxライブラリ群を手軽に、そして無制限に貸してくれるのがGoogle AJAX Libraries API

jQuery本家からダウンロードする場合

jQuery本家
もちろん、jQueryをダウンロードして、自分のサーバーや、ローカル環境に設置して読み込むことも出来ます。
本家サイトからjQuery本体をダウンロードする場合、必ずMinified and Gzippedをダウンロードします。これは安定かつ、改行を全て排除して圧縮済みのファイルです。反対にUncompressed Codeは改行も、コメントアウトも大量に入っており、ファイルそのものも重たいです。
自分でさらにカスタマイズして使いたいプロフェッショナル向けというところでしょうか。

jQueryの読み込みと簡単なスクリプトの実行

ではjQueryを読み込んで、簡単なスクリプトを実行してみます。
全体の読み込みが完了してから

の中身をalertの中に呼び出します。

<script type="text/JavaScript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/JavaScript">
jQuery(document).ready(function(){
alert(jQuery('p').text());
});
</script> <p>あああああああああ</p>

jQuery(document).ready(function(){});の意味

多くのWEBデザイナーの方はjQuery(document).ready(function(){});の意味を理解されていません。他ブログの解説には『jQueryの書き出しの決まり文句』としている場合がありますが、それは間違いです。

DOMがロードされて操作・解析が可能になったタイミングで関数を実行します。』とあります。

DOMって何さ

Document Object Modelの略称のことで、HTMLやXML文書を取り扱うためのAPIのことです。
(さらに意味が分かりませんね)
下記のソースコードのあいうえおかきくけこに変更したい、これがDOM操作です。

<p>あいうえお</p>

ほぼ全てのブラウザでデフォでDOMはあらかじめ扱えるようになってありますから、DOM操作をするにあたって特別な設定はありません。

ready()の解説に戻りますよ~

つまりですね、ready(function(){})の中に書いたものは、jQuery(document)の読み込みを待ってから、処理を実行するということです。
(HTMLやCSS、画像など、WEBページの表示に必要なものを一通り読み込んでから)

window.onloadとの決定的な違い

よく通常のJavascirptで使われる
window.onloadとは決定的な違いがあります。それは、ウィンドウ(ページが)開かれた瞬間に処理を実行されるので、もし重たい処理が実行されてしまえば、処理が完了するまで一切WEBページのHTMLや画像、CSSは読み込まれません。これはユーザビリティを考えると、とてもいいことですね。

jQuery(document).ready(function(){});を使わない方法

ready()を使わなくても、jQuery(document).ready(function(){})と全く同じことをする方法があります。(ソースコードはより短いほうがいいですものね)
それは、欲しい処理を、</body>の直前に書くということです。
HTMLやCSS,もちろんJavascriptは上から順に読まれていきます。
つまり、jQueryでの処理も一番最後に書いてあげればready()メソッドを使わないでjQuery(document).ready(function(){})と同じことが出来るわけです。

<script type="text/JavaScript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<p>あああああああああ</p>
<script type="text/JavaScript">
alert(jQuery('p').text());
</script>

redy() メソッドを使えばどこに処理を書いても、DOMの読み込み完了してから処理が実行できますし、処理を</body>の最後に書くことが出来たら、それもまた同じことです。
どちらも好きなほうを使ってください。
なお、このサイトのサンプルではredyメソッドを使う方向で対応します。
(なんかjQuery使ってる感がするから)

jQuery checked数のカウントで重大な勘違い

jQueryのchecked数のカウントについて。
よくリファレンスで下記のように書いて、checkedの数を取得する方法が紹介されています。

var n = $("input:checked").length;

こうやったほうがいい。

var n = $("#hoge :checkbox:checked").length

詳しい説明はまた後日します。

PostgreSQL ユニークの追加

PostgreSQL ユニークの追加

テーブル名hogefieldにユニークを追加

ALTER TABLE hoge ADD UNIQUE (field)

PostgreSQL ユニークの削除

テーブル名hogefieldのユニークを削除

ALTER TABLE agency DROPUNIQUE (login)

なお、phppgadminにて確認すると、ユニークが追加されるとこんな表示になります。

localStorageを使ってユーザー設定を保存する

localStorageを使って設定フォントサイズを保存しよう

今回はlocalStorageを使ってユーザー設定を保存するプログラムを紹介します。
よくJavascriptベースでページ内の文字を変更するボタンがありますね。あれをlocalStorageを使って設定を保存し、ページをリロードしたり、閉じたりしても設定されたフォントサイズが呼び出されるようにします。
今回のスクリプトは前回のlocalStorageメモよりは簡単です。

サンプルスクリプト

まずはサンプルスクリプトから

<div id="Sizer">
<input type="button" value="小" id="small"/>
<input type="button" value="中" id="middle"/>
<input type="button" value="大" id="large"/>
</div>
<div id="text">文字文字</div>
$(document).ready(function(){
var hoge = localStorage.getItem("font_size");//strageに保存された設定呼び出し
$("head").html(hoge);//headにスタイル書き出し
}); $("#small").click(function(){
localStorage.setItem("font_size", "<style>.fontsize{font-size:0.5em;}</style>");
var hoge = localStorage.getItem("font_size");
$("head").html(hoge);//headにスタイル書き出し
});
$("#middle").click(function(){
localStorage.setItem("font_size", "<style>.fontsize{font-size:1em;}</style>");
var hoge = localStorage.getItem("font_size");//strageに保存された設定呼び出し
$("head").html(hoge);//headにスタイル書き出し
});
$("#large").click(function(){
localStorage.setItem("font_size", "<style>.fontsize{font-size:2em;}</style>");
var hoge = localStorage.getItem("font_size");//strageに保存された設定呼び出し
$("head").html(hoge);//headにスタイル書き出し
});
</script>

動作説明

DEMOのURLをブラウザより確認して下さい。ほとんどのブラウザは対応されていると思いますが、うまくいかない場合はChromeやOperaで試してください。
前回はメモでフォーム内のテキストを保存しましたが、今度はCSSのスタイルを保存しています。
大や小ボタンを押してからブラウザを閉じて、再び開くと前回の設定が保存されているのが確認出来ます。
ボタンのいずれかが押されたらfont_sizeというストレージ名で保存します。

 localStorage.setItem("font_size", "<style>.fontsize{font-size:2em;}</style>");

失敗例

localStorageでの失敗例は、localStorageは文字列しか保存できないのに、DOM要素を入れた場合
例えばこのように、フォントサイズの変更が入ったクラスを付与するパターン。マークアップエンジニアの方はHTML上にCSSが書いてあるのは我慢ならんので クリックされたらクラスを付与したいと思うはず。

localStorage.setItem("font_size", $("#text").addClass("middle"));
alert(localStorage.getItem("font_size"));

動作説明

どうでしょうか?ボタンを押された瞬間はフォントサイズが変わり、クラスが付与されたことは確認できましたが、ブラウザを閉じて、もう一度開くと、フォントサイズはデフォルトに戻っています。
アラートが出ていますが、このアラートはlocalStorageに何が入っているのかを確認したもので、結果はobject Objectとなり、確認することが出来ません。

localStorageのまとめ

結局文字列ベースで保存するのが一番です。マークアップの方からすると若干気持ちが悪いですが。

補足

localStorageは、ローカル環境だと完全に動かないケースもあります。サーバーにアップすると問題なく動き、ローカルだと今回のサンプルは動きませんでした。
IEに関しては、localStorage対応でも、インターネットオプションにlocalStorageを使う旨設定しておかないと、これも動いてくれません。
localStorageはサーバーにスクリプトを設置して、インターネットオプションをきちんと確認してから使うように心がけましょう。

localStorageまとめと注意事項

HTML5 APIの一種であるlocalStorage。実際に使ってみたところ、各ブラウザ間で挙動が異なったりで戸惑うことが多かったので、localStorageについてまとめと注意事項を説明したいと思います。

主な使い道

・ちょっとしたメモアプリに
・ユーザーの設定の保存(例えば背景や文字サイズの設定を保存)
・スマホサイトの高速化に

localStorageのプロパティ

length … ストレージへ格納されてた数を取得
key(index) … 項目のインデックスを指定してキーを取得
getItem(key) … キーを指定して値を取得。
setItem(key, data) … 指定されたキーを保存
removeItem(key) … 指定されたキーを削除
clear() … ストレージをクリア

対応ブラウザ

ブラウザ バージョン
Internet Explorer 8
Firefox 3.5+
Safari 4.0
Goole Chrome 4.0
Opera 11

localStorage非対応ブラウザでの実装方法

localStorage非対応ブラウザでもGearsにて実装することが可能。
これにより、IE7以前や、Android1.6でもlocalStorageを実装することが出来る

そもそもGearsって何?

現在GoogleはWebアプリのオフライン化を実現する拡張機能「Gears」を終了して、HTML5へ移行すると発表しました。
ただ、これからもlocalStorageをはじめ、非対応ブラウザにHTML5 APIのような拡張機能を持たせるときにはお世話になることでしょう。
第1回 そもそもGoogle Gearsって何?
IE6でWeb Databaseをサポートするハック

基本的な使い方

よく使うのはこんなところ

var hoge = localStorage.getItem("text");//textというキー名で保存したデータの呼び出し
localStorage.setItem("hoge", hogehoge);//hogeというキー名で変数hogehogeを保存
localStorage.clear();//全ての key と 値 を削除

localStorage注意事項

・IEだとlocalStorage対応バージョンでも、あらかじめ設定をONにしていないと動かない。
(これも最初知らず、ハマりました)
・IEではローカル環境ではlocalStorageが動作しない。サーバーに設置してから。

推奨されない書き方

var value = localStorage["key"];
localStorage["key"]= var value;

このような書き方をするサンプルも多いですが、基本的には推奨されません。きちんとgetItem("text")
と書くのが正しい。

【超重要】

HTML5 の仕様では、localStorage にオブジェクトを突っ込めるそうですが、ブラウザによっては実装できないことが多い。そのためOpera、Chromeでは問題なく実装できても、Firefox、IEではうまくいかないことも。
オブジェクトを代入する場合、一度文字列に変換してからストレージをセットするのがよいらしい。
たとえば日時をセットする場合

localStorage.setItem("date_time", (new Date()).toString());   //保存日時

localStorageはいい感じ: ぺるたごブログ

localStorage役立ちリンク

その他localStorageのお勉強に役立ちそうなリンク
第14回HTML5とか勉強会
[JavaScript][HTML5][localStorage]localStorageの挙動と簡単なラッパー – but hopeful
ブラウザ別、localStorage の削除に関わる所作 :WEB 職人

localStorageを使って、簡易メモ帳を作ってみよう

localStorageとは

JavaScriptコードからアクセスできて、テキスト形式の任意のデータを保存できます。例えばサーバー側からデータをキャッシュとしてローカルに保存することが出来、localStorageではオフライン状態でも保存したデータを見ることが出来ます。
スマートフォンサイトなどではこの機能を使ってサイトの高速化を実現できます。

localStorageの基本プロパティ

localStorageでは下記の項目のプロパティを使うことが出来ます。なお、保存できるのはテキストデータのみです。画像などの保存は出来ません。

length ストレージに保存されている項目の数
key(index) 指定されたインデックスのkeyの取得
getItem(key) keyの値を取得
setItem(key, data) keyにdataを保存する
removeItem(key) 指定されたKeyの値削除
clear() ストレージ全体を削除

localStorage簡易メモ

ざっとコードを解説しますと、
・window.onloadでページを開いたら処理を開始
・ストレージ内のデータを読み込み
・ストレージのデータが空でなければ呼び出し
・$(“#del”).click()で削除ボタンのクリックでストレージ削除してリロード
・$(“form”).submit()で送信ボタンが押されたらストレージデータの更新

<!DOCTYPE html>
<html><head><meta charset="utf-8"></head><body>
<h1>strageメモ</h1>
<div id="msg_div"></div>

<form method="post">
<textarea id="main_txt" cols="80" rows="30"></textarea>
<input type="submit" value="送信"/>
</form>
<input type="button" value="削除" id="del"/>
<!-- Android 1.6対策 -->
<script type="text/javascript" src="./js/gear5-0.3.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

<script type="text/javascript">
window.onload = function() {
// メモの読み込み
var body = localStorage.getItem("memo");//strageに保存されたメモ
var date_time = localStorage.getItem("date_time");//strageに保存された日時
if (body != null) {
$('#main_txt').val(body);
$('#msg_div').text(date_time);

}
};

//削除ボタンを押したらストレージ削除
$("#del").click(function () {
localStorage.clear();
window.location.reload();
});

//送信ボタンを押したら、ストレージを保存
$("form").submit(function() {
localStorage.setItem("memo", $('#main_txt').val());
localStorage.setItem("date_time", new Date());//保存日時
});

</script>
</body>
</html>