PCサイトから長らく離れている間にjQueryが1.4になりました。
何が変更されて何が追加されたっていうのは「jQuery 1.4 API Cheat Sheet — Future Colors」というサイトでうまくまとめられています。
bind()で複数イベントが追加できたり、処理を遅らせるdelay()等があったりします。
基本的に互換性は保ってるとのことだけど、そのままのコードだと動かないところもあります。
例えば1.3だとこれでtitleというnameのinputの値がとれたけど1.4ではエラーになります。
$('input[@name=title]').val();
1.4では下記のようにtypeを明示する必要があります。
$('input:text[@name=title]').val();
jqueryのfunction名は直感的でわかりやすいなぁ。
opensocialのデータの保存方法は、Key-Valueペアの文字列情報になります。
非常に高速に単純明快で扱いやすいのですが、とたんに扱いにくくなりコードが冗長化しがちです。
mixiアプリはjavascriptなんでそんな時jsonで保存しとくとラクチンです。
幸いな事にopensocialにはjson化するメソッドが既に備わっています。
下記がarrと言う名前のJSONデータが作成を保存する方法です。
情報の永続化
var user_id = opensocial.IdSpec.PersonId.VIEWER;
var arr = {};
arr['title'] = "hoge";
arr['rank1'] = "rank1";
arr['rank2'] = "rank2";
arr['rank3'] = "rank3";
// エンコードしてjson化
var jsonvalue = gadgets.json.stringify(arr);
var req = opensocial.newDataRequest();
req.add(req.newUpdatePersonAppDataRequest(user_id, "jsonvalue", jsonvalue));
永続化された情報の取得
var user_id = opensocial.IdSpec.PersonId.VIEWER;
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(user_id), "viewer");
var fields = [ "jsonvalue" ];
req.send(function(response) {
if (response.hadError()) {
alert(response.getErrorMessage());
} else {
var myId = response.get("viewer").getData().getId();
var data = response.get("viewer_data").getData();
var str = data[myId]["jsonvalue"];
str = gadgets.util.unescapeString(str);
var arr = gadgets.json.parse(str);
// hogeが出力される
alert(arr.title);
}
});
無効処理と言う程でもないけど、mixiアプリはアプリ自体は自前のサーバーにアップします。
そのアプリをmixiから呼び出して実行する仕組みです。
毎回mixiから自前サーバーへの接続があるのも面倒な話なんで、アプリはmixiのキャッシュサーバーに取り込まれます。
これはこれでいいんだけど、開発時やデバッグ時にはかなり厄介です。
で、このキャッシュを除去するには、URLの後に下記のパラメーターを付与します。
&nocache=1
これで毎回修正を加えたアプリを取得しにいきます。
ただこれでもxmlの中に
<script type="text/javascript" src="http://hoge.com/mixiapp/opensocial-jquery.js"></script>
のように外部ファイルを読み込む記述があるとこれは引き続きキャッシュを読み込みます。
これを除去するのは、使い古されたやり方だけどURLの後ランダムな文字列(Math.random())を付与します。
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest('OWNER'), 'owner');
req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
req.send(function(data) {
var owner = data.get('owner').getData();
var oid = owner.getField(opensocial.Person.Field.ID);
var viewer = data.get('viewer').getData();
var vid = viewer.getField(opensocial.Person.Field.ID);
var viewer = data.get("viewer").getData();
if(vid == oid){
//viewerがownerである時
$("#owner").show();
$("#viewer").hide();
m.getContents();
}else{
//viewerがowner以外の時
$("#owner").hide();
$("#viewer").show();
v.getContents();
}
});
mixiアプリを仕事ですることになったのでメモ。
ユーザー情報をとってくるサンプルです。
特定のユーザー(243944402)からプロフィールURLを取得します。
profile URL is <span id="target"></span>
<script type="text/javascript">
function init() {
var params = {};
params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [
opensocial.Person.Field.PROFILE_URL,
];
// ユーザーIDを指定
var uid = "243944402";
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(uid, params), "spec");
req.send(function(data) {
var viewer = data.get("spec").getData();
var profileUrl = viewer.getField(opensocial.Person.Field.PROFILE_URL);
document.getElementById("target").innerHTML = profileUrl;
});
}
gadgets.util.registerOnLoadHandler(init);
</script>
特定のユーザー(243944402)のマイミクのプロフィールURLを取得します。
複数のデータがとれるのでeachでまわす。
<div>profile URL is <span id="target"></span></div>
<script type="text/javascript">
function init() {
// ユーザーIDを指定
var uid = "243944402";
var user_info = {};
user_info[opensocial.IdSpec.Field.USER_ID] = uid;
user_info[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
var idSpec = opensocial.newIdSpec(user_info);
var params = {};
params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [
opensocial.Person.Field.PROFILE_URL,
];
var req = opensocial.newDataRequest();
req.add(req.newFetchPeopleRequest(idSpec, params), "friends");
req.send(function(data) {
var friends = data.get("friends").getData();
friends.each(function(friend) {
var prof = friend.getField(opensocial.Person.Field.PROFILE_URL);
document.getElementById("target").innerHTML += prof + '<br>';
});
});
}
gadgets.util.registerOnLoadHandler(init);
</script>
このアプリをインストールした人のプロフィールを取得したい場合は、opensocial.IdSpec.PersonId.OWNER、
このアプリを今使ってる人(ユーザー自身)のプロフィールを取得したい場合は、opensocial.IdSpec.PersonId.VIEWER
をそれぞれuidに指定。
uidのユーザーIDはintとして扱うとエラー吐くので注意。
javascriptには他言語と違い、数字の桁合わせ(ゼロ詰め)がありません。
いつも代用する手段はこれ。
2桁に合わす。桁数に応じて適宜数字を変更。
function test() {
var date = new Date();
var month = "0" + (date.getMonth() + 1);
var zero_month = month.substr(month.length - 2);
alert(zero_month);
}
ポイントとしては、4行目の(month.length – 2)。
ここをマイナス指定してしまうとIEで動かなくなります。
jqueryのプラグインといえば、エフェクト系が多いのですがform.jsはその名の通りformの値を扱うの便利なプラグインです。
例えばこんなフォームがあったとして、
<form action="/hoge.php" name="search" method="GET" id="comSearchForm">
<table>
<tr>
<th>
フリーワード
</th>
<td>
<input name="word" type="text" value="">
</td>
</tr>
<tr>
<th>
生年月
</th>
<td>
<select name="start_year">
<option value="">----</option>
<option value="2006">2006</option>
<option value="2007">2007</option>
<option value="2008">2008</option>
</select>年
<select name="start_month">
<option value="">--</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>月
</td>
</tr>
</table>
<div class="submit">
<input type="hidden" name="action" value="search" />
<input type="button" value=" 検 索 " onclick="searchCom();"/>
</div>
</form>
それぞれの値をajaxでphpに渡したい場合(検索なんかの時)に、form.jsを使えばフォームの値を一発でパラメータに変換してくれます。
queryString = $('#comSearchForm').formSerialize();
queryStringはこんな感じになります。
word=%E3%81%BB%E3%81%92&start_year=2006&start_month=02&action=search
jqueryでフォームの値を取得する時、毎回調べてしまうのでまとめとく。
ID指定してattrとかでもいけるんだろうけど、checkboxの時に統一できないんで。
HTML
<form name="form">
タイトル
<input type="text" name="title" id="title">
<br />
コメント
<input type="textarea" name="com" id="com"></textarea>
<br />
血液
<input type="radio" name="blood" id="blood_A" value="A" />A型
<input type="radio" name="blood" id="blood_B" value="B" />B型
<br />
趣味
<input type="checkbox" name="hobby" id="hobby_A" value="サッカー" />サッカー
<input type="checkbox" name="hobby" id="hobby_B" value="野球" />野球
<br />
都道府県
<select name="pref">
<option value="東京">東京</option>
<option value="大阪">大阪</option>
</select>
<input type="button" value=" クリック " onclick="show()" />
</form>
javascript
<script type="text/javascript"><!--
function show() {
$("#result").html('');
//name
$("#result").append($('input[@name=title]').val());
// textarea
$("#result").append($('input[@name=com]').val());
// radio
$("#result").append($('input[@name=blood]:checked').val());
// checkbox
$('input[@name=hobby]:checked').each(function(){
$("#result").append($(this).val());
});
// select
$("#result").append($('select[@name=pref]').val());
}
// --></script>
使いそうで使ってなかったjqueyのeach関数。
下記のようにDOMをループしてリンク先を全て変更したい時等に使います。
<ul class="clearfix">
<li><a href="link1.html">リンク1</a></li>
<li><a href="link2.html">リンク2</a></li>
<li><a href="link3.html">リンク3</a></li>
<li><a href="link4.html">リンク4</a></li>
<li><a href="link5.html">リンク5</a></li>
</ul>
$(document).ready(function(){
j$("ul li a").each(function(i){
var url = j$(this).attr('href');
url = url + '\?ref=blog';
j$(this).attr('href', url);
});
});
するとページがロードされるとこんな感じに代わります。
<ul class="clearfix">
<li><a href="link1.html?ref=blog">リンク1</a></li>
<li><a href="link2.html?ref=blog">リンク2</a></li>
<li><a href="link3.html?ref=blog">リンク3</a></li>
<li><a href="link4.html?ref=blog">リンク4</a></li>
<li><a href="link5.html?ref=blog">リンク5</a></li>
</ul>
実際jsでリンクを変更って余り使わないだろうけど、classを変更したい時はテキストを変更したい時に使えます。
jsでインターフェイスの幅が広がったと思うけど、本当のユーザビリティーってなんだろうと思う。
「直感」で分かるインターフェイスはもちろん重要。
しかし、
- ユーザーは「次へ」をクリックするとページ遷移することに慣れてしてまってる。
- 開発者はユーザービリティを考慮してページ遷移させずにajaxで次ページを表示する。
で、ブラウザの戻るをクリックするとユーザーが望んでるページに戻らない。
開発者や制作会社なんかは後者を意識しがちだけど、ユーザーの慣れとか体験っていうのを無視してしまうのは、本来のユーザビリティっての無視してる気がする。
後進的と言われようと、そこは重要なところ。