2011/12/26

[Rapphae.js] オンマウス時になめからなアニメーションで枠線を表示させる




JavaScriptのライブラリはmootoolsを使ったので、そのまま使うってわけにはいかないかもしれませんが…

これ、IE6,7,8でもそれなりに滑らかにアニメーションするんですよ。SVGじゃなくてなんとかいうのを使うらしいです。
IE6に関しては「もうあんなやつのこと忘れちまいなよっ」って感じですが…

IE9からSVGに対応してるみたいですし、スマートフォンも対応してそうだから今後使っていけるといいな。

上のサンプルだとsvgのアニメーションはRaphaelの機能を使ってるんだけど、jQueryとかのアニメーションでもやれるみたい。
機能が重複してるのに、両方とも読みこまないといけないのがちょっともったいない

2011/12/21

[Mootools] 要素の高さ、幅を取得する


いつも忘れてしまうのでメモ
Mootoolsで高さなどのサイズを取得する方法
elem.getSize().y //高さ
elem.getSize().x //幅

2011/12/20

[JavaScript] iPhone で alert, confirmを使うと動きが変になった


ボタンを押すと「***していいですか?」という確認ダイアログが出てきて、「OK」を押すと処理を続けて、「キャンセル」を押したら中断ってな処理を作った。
ダイアログはtouchendイベントで出てくるようにした。
どっちを押したとしても、それぞれの処理をして終わり…になる予定だったが、ダイアログが閉じた後、ボタンをタッチすると(touchstart)指を離さなくても、もう一度同じダイアログが表示されるようになった

alertでも同じようなことが一度あった。iPhoneだとalertやconfirmでダイアログが出ると、イベントが途中で止まって、もう一度触ると止まったとこから再度動き出す…ようなイメージ。

対処法::クリックイベントの中身を全部setTimeoutで囲った。
elem.addEventListner("click", function(){
 setTimeout(function(){
  //クリック時の処理
 }, 0);
});

2011/12/19

Rphael.js を使って SVGで四角い線を表示させてみる

SVGを使うのに便利なライブリRaphael.jsを使って枠線を表示してみる


var container = $("#id");

//SVGを格納する要素を作成
var newElem = document.createElement("div");

//サイズ
var width = 100;
var height = 100;

//描画エリアを指定する要素を作成。Raphaelは全部これで始まる
//格納する要素を指定せずに作ることもできるけど、その時はbody直下に追加されるようだ
var paper = Raphael(newElem, width, height);

//path要素を作成。指定方法はちょっと面倒…。
var stroke = paper.path("M0,0L" + width + ",0L" + width + "," + height + "L0," + height + "L0,0z")
 .attr({
  //線の色と太さを設定
  "stroke": "#ffd400",
  "stroke-width": 16
 });

//要素に追加
container.append(newElem);

参考:path要素の解説

[JMeter] Ajaxでのアクセステスト

ajaxでpostして、レコードを削除しているページがあったので、そのバリデータテストをしたかった。
サーバー側でajaxかどうかとpostされているかどうかを判定していたので、通常のアクセスだとはじかれてしまう。

対応
スレッドにHTTPヘッダーマネージャーを追加
追加するヘッダーは
名前: X-Requested-With
値: XMLHttpRequest

これを設定した後でHTTPリクエストをPOSTで行えばajaxでのアクセスもOK

2011/12/13

[WordPress] Viper's Video QuicktagsでYoutubeの動画が出なくなった場合の対応

Youtubeの埋め込み用コードが変更になったみたい。
http://www.youtube.com/watch?v=*****

http://youtu.be/******
になった

youtu.beってドメイン。

この新しいURLにWordPressのプラグインの「Viper's Video Quicktags」っていうYoutubeを貼り付けるクイックタグを作ってくれるプラグインが対応してなくて、エラーが出た。

プラグインのファイルをちょっと変更して対応した。
(プラグインのバージョンは2011/12/13で最新の6.3.3)

■変更するファイル
/wp-content/plugins/vipers-video-quicktags/vipers-video-quicktags.php

■変更する箇所
2866行目
// Playlist URL ( http://www.youtube.com/playlist?list=PLXXXXX )
if ( false !== stristr( $content, 'playlist' ) ) {
 //省略
}
// Legacy playlists ( http://www.youtube.com/view_play_list?p=XXX )
elseif ( FALSE !== stristr( $content, 'view_play_list' ) ) {
 //省略
}
//ココから追加箇所
elseif ( FALSE !== stristr( $content, 'youtu.be' ) ) {
 preg_match( '#http://(www.youtu|youtu|[A-Za-z]{2}.youtu)\.be/([\w-]+)(.*?)#i', $content, $matches );
 
 if ( empty($matches) || empty($matches[2]) ) return $this->error( sprintf( __('Unable to parse URL, check for correct %s format', 'vipers-video-quicktags'), __('YouTube') ) );
 
 $embedpath = 'v/' . $matches[2];
 $fallbacklink = 'http://www.youtube.com/watch?v=' . $matches[2];
 $fallbackcontent = '' . __('YouTube Preview Image', 'vipers-video-quicktags') . '';
}
//ココまで追加
// Normal video URL
else {
 //省略
}


Normal video URLってコメントを目印にして探して。

もし変更するなら、変更前の元のファイルをコピーしといて、すぐ戻せる状態にしてから試したほうがいいと思う。

2011/12/09

[CakePHP] ビューで共通に使う素材を作成する

CakePHPではメニューとか、フッターとか、共通で使う部分を1つのファイルとして作成して、共通で使いまわすエレメントってのがある。

設置場所:/app/views/elements
拡張子はctpにする。

・呼び出し方(ビュー内)
$this->element('parts');
これで/app/views/elements/parts.ctpが読み込まれる

・変数を渡して、エレメント内で使用できる
//ビュー側
$this->element('parts', array(
 'value' => 100,
 'key' => 'お小遣い'
));
//エレメント側
円です


参考:
CakePHPマニュアル 3.10.3 エレメント

[php] 配列から値を取得する。ランダム・最大・最小

PHPで配列から値を取得する方法

・ランダムに取得したい場合
$arr[array_rand($arr)];

・最大値を取得したい場合
max($arr);


・最小値を取得したい場合
min($arr);

2011/12/06

[JavaScript] SVGが使えるか判定する

IEでもバージョン9からSVGに対応してるらしいので、SVGをもっと使っていきたい。
けど、IE8まではSVGに対応していないので、SVGが使えるかどうかをJavaScriptで判定する。

簡単
var ableSVG = (window.SVGAngle !== void 0);
SVGColorSVGAngleってプロパティがあるかどうかで判定する
void 0ってのはundefinedと同じ意味なので、SVGColorSVGAngleがないってことはSVGは使えないってこと


--add[2011/12/9]

SVGColorで判断してたんだけど、そんなプロパティはfirefoxにはなかった。


参考:
SafariとChromeを判別してみる

2011/12/05

オンマウス時に出す枠をSVGでなめらかに表示&アニメーション

SONYのヘッドフォンのサイト見ていて、オンマウス時のアニメーションがなめらかで綺麗だったので、どうやってるのか調べてみた

見たサイト↓
http://discover.store.sony.com//piiq/

水色の枠はSVGで表示している。
FLASHなんかでは良くみる表現。

ボーダーをつけたdivをオンマウス時に縮小することで、枠を表示させてもいいんじゃないのと思ったけど、firefox7ではアニメーションがコマ落ちしてガタガタだった。

で、やりかた。
線の幅をアニメーションで変更してる。
線の幅は、線の中心から両方に広がっていくので、10pxの幅の線を出したい場合は、倍の20pxに設定すると、中心から外側と内側にそれぞれ10pxの線がでる。
外枠はoverflow:hiddenにしとかないと、外側の線まで出てしまうので注意。

HTML

JavaScript(jQueryを使ってます)
$(".item").hover(function(){
 $(this).find(".border").css("opacity", 1).animate({
  "stroke-width": "10px"
 });
},
function(){
 $(this).find(".border").animate({
  "stroke-width": "0px"
 }, {
  complete: function(){
   //アニメーションが終わったら非表示
   $(this).css("opacity ", 0);
  }
 });
});


SVGがつけるかどうかをJavaScriptで判定するなら→「SVGが使えるか判定する」(Raphael使ったほうがいいと思うけど…)

参考サイト:
http://www.hcn.zaq.ne.jp/___/SVG11-2nd/paths.html



-- add 2012/12/16
Raphael.jsを使ってやってみました
オンマウス時になめからなアニメーションで枠線を表示させる
--

2011/12/01

[CakePHP] 別のテンプレートを使いたい場合

条件によって、使用するテンプレートを切り替えたい場合などに

$this->render('template_2'); //この場合はtemplate_2.ctpが読み込まれる
参考: ビューテンプレートの変更方法

2011/11/30

[CakePHP] 子・孫まで。複数の入れ子になったモデルを連結して取得したい

cakePHPでデータを取得する際にhasManyなどの子のモデルに、更に孫のモデルをくっつけて取得したくなった。

・モデルで指定する場合
$recursive = 2; //これで2階層目まで取得する

・コントローラで指定する場合
$this->Model->find('first', array('recursive' => 2);
両方とも、数字を変更すれば取得しにいく階層の深さが変わる

参考:
CakePHPで3つ以上の複数テーブルを結合

[iPhone] タッチイベントとクリックイベント

iPhoneではタッチイベント→クリックイベントの順に処理されるみたい。

スマートフォン向けサイトで「ページ上部に戻る」ボタンを置いた。
クリックイベントだとAndroidでもっさりな動作に感じるので、touchendイベントで反応するようにした。

touchendイベント

ページ上部にスクロール

clickイベント

スクロールしてるから、クリックした場所にはすでに別のモノが…

その別のモノをクリック!

って感じになった。

なので今回はクリックイベントのみ処理するように変更した。

タッチエンドイベントをクリックイベントがわりにするとこまごまと引っかかる。
まあ、対処できないようなことではないのでいいんだけど…。

[CakePHP] 404ページを表示したい

CakePHPで404ページを出したい時は…

/app/view/errosディレクトリにerror404.ctpファイルを設置する。

だけ。


レイアウトを変更したい場合なんかは、app直下にerror.phpというファイルを作って、その中で色々と処理をすればいいらしい

コントローラー側では
$this->cakeError('error404');
と書く。

参考:
CakePHPで404エラー画面を作る

cakeのバージョンは1.3です

2011/11/28

ログを残すなら正常時でもログを残そう

バカみたいな話なんだけど…。

cronで毎日、データベース内で不要になったレコードを削除する処理をしていた。
処理が正常に動いているのは確認できていたので、レコードの不具合など、予想外のエラー時のみログを残すようにしていた。
それだと正常に削除されていた場合は記録が残さない。
なので、あるレコードが削除された日時を知りたいという話になって困った。

なぜ正常時のログを残さなかったのが、自分でも思い出せないんだけど…。
もしかして、ログのファイルがでかくなるのが嫌だとかそんな理由だったのかも。

一応何度も同じミスをする自分宛にメモ

2011/11/25

[JavaScript] スクロールの終了時にイベントを起動する

JavaScriptでスクロールが終わった時に、なにか処理をしたい時がある。
要はスクロールするとついてくるメニューの処理みたいな感じ
ああいうのはスクロール中もついてくるけど、今回のは終わるまで何もしない。

スマートフォン向けにブラウザの下部に出てくるバナーなんかで、スクロールすると消えて、スクロールが止まると表示されるやつ、あんな感じ。
var timeId;

window.addEventListener("scroll", function(){

 //解除
 clearTimeout(timeId);

 //時間をリセットしてセットし直す
 timeId = setTimeout(function(){
  //処理
 }, 500);
});

//最初に一回動かす
timeId = setTimeout(function(){
 //処理
}, 0);

iPhoneからのメールをデコードするとタイトルが文字化けする

メールで投稿できるブログシステムみたいなやつで文字化けすることがあるというので対応した。

文字化けするのはiPhoneからのメール
受信したメールを分解して処理しているのはPEARのMail_mimeDecode

調べてみるとiPhoneで送られるメールのタイトルと本文で文字コードが違うことが原因だった
Mail_mimeDecodeだとタイトルの文字コードは本文と同じものとして処理しているのかも。

結局Mail_mimeDecodeではなくZend_Mail_Partを使うことにした

参考:
iPhoneから送ったメールが文字化けする問題について

2011/11/24

高速化のためだけにアプリケーションキャッシュを使ってもいいのかな?

HTML5の新機能で、Webアプリケーションをオフラインでも使えるようにするための機能としてアプリケーションキャッシュってのがある。

必要なファイルをブラウザ側でキャッシュさせて、インターネットでファイルを読み込むんじゃなくて、キャッシュさせたファイルを利用する。

スマートフォン向けのサイトを作っていて、オフラインで使ってもらうことは考えてないんだけど、アイコン画像とかJavaScript、Cssファイルなんかもキャッシュさせとくと、ものすごく高速化できる。
通常の電話回線でもwifi以上の体感スピード。

でも、この高速のためにファイルをキャッシュさせるってのは、もともとのオフラインでアプリケーションを利用できるようにするための機能ってのとは全然違う使い方なんだけど…

いいのか?
うーん…わからん


参考:
[HTML5] アプリケーションキャッシュの使い方

[WordPress] 一覧ページで前後のページへのリンクを出す

記事の一覧ページなんかで、「次のページ」とか、「古い記事へ」とかのリンクを出したい。
ブログなんかには当然のあるやつ。
next_posts_linkとprevious_posts_linkを使う

previous_posts_link('<<新しい記事を見る');
next_posts_link('古い記事を見る>>');

2011/11/18

MooToolsでAjaxする方法

MooToolsでAjaxをするにはRequestを使う。
//まずは設定
var req = new Request({ 
 url: "/sample/dir" ,
 onSuccess: function(res){
  //成功時
 },
 onFailure: function(xhr){
  //失敗時
 }
});

//通信開始
req.send();

■画像、JavaScrip、cssを動的に読み込む
JavaScript、css、画像などを動的に読み込みたい場合はAssetsというのもある。
これはmootools-coreには入っていないのでmoreを別途入れないと使えない
こっちはXMLHttpRequestで通信するのではなくて、エレメントを作ってる
//取得するだけなのでnewしない。
//image要素が返ってくる
var myImage = Asset.image(画像へのパス);

//script要素が返ってくる
var myJs = Asset.javascript(ファイルへのパス);

//link要素が返ってくる
var myJs = Asset.css(ファイルへのパス);


参考:
MooTools基礎文法最速マスター
Assetsメソッド: javascript

2011/11/16

スマートフォンのユーザビリティ

スマートフォンのユーザビリティに関して、参考になる記事があったのでメモ

スマートフォンサイトに適したユーザビリティとは?【リサーチ】

要点は

・タブは強調することで「迷わず操作できる」「見やすい」印象に
タブの文字色だけでなく、タブの高さ変えた方がよい


・アコーディオンがある場合は、左側にナビゲーションを設置した方がわかりやすい
アコーディオンを表すボタンはその枠の左側に置く
「+」と「▼」だと差はない


・複数のバナーをフリック機能を用いて見せる場合、一度に表示させるバナーの数は1つが「操作しやすく」「押しやすい」
フリックよりも「次」「前」ボタン
次のバナーが小さく出てたり…よりも1つだけ出てるほうがよい


・小バナーは順次見せるよりも、セットで切り替わる方が「文字が見やすく」「負担を感じない」
ヤフーのスマートフォンサイトのバナーみたいなやつかな
バナーが3つ出てる状態で、「次へ」ボタンを押した時に3つとも入れ替わるほうがよい


・サブウィンドウを表示させる場合、スライド形式によって表示するよりもモーダルウィンドウ形式の方が支持されている
jQuery Mobileは横スライドで、iPhoneは下から系が多いイメージだけど、モーダルがいいのか。
PCのイメージと近いのかも


・サブメニューを表示させる場合、アコーディオン形式で表示した方が「リンク・ボタンが押しやすく」「操作しやすい」
コンテンツの上にかぶせて表示させるよりも、コンテンツをずらして、メニューを表示させる枠を作ったほうがよい


うーむ。参考になった
PCよりも直感的な動作になる分、わかりづらいとか使いづらいがストレスになりそう

[CakePHP] コントローラー内で共通の処理をまとめる

コントローラー内で共通の処理をまとめることができる

1.beforeFilter()
それぞれのアクションが実行される前に呼び出される

2.beforeRender()
アクションを実行した後に呼び出される

3.afterFilter()
レンダリングも終了した後で呼び出される


呼ばれる順番は
beforeFilter()

アクション

beforeRender()

レンダリング

afterFilter()

[PHP] file_get_contents でタイムアウトする時間を設定する


file_get_contentsでhttp://から指定したURLを読み込む時に、読み込みたいページからレスポンスがないと、プログラムがそこで止まってしまう。

デフォルトの設定だと60秒とかになってるんで、まあ、待つ人おらんよね。

今回はタイムアウトする時間を変更して対応した。
//後で戻せるように設定を取得しておく
$org_timeout = ini_get('default_socket_timeout');

//5秒以上かかったらタイムアウトする設定に変更
$timeout_second = 5;
ini_set('default_socket_timeout', $timeout_second);

$data = file_get_contents($url);

//設定を戻す
ini_set('default_socket_timeout', $org_timeout);


ini_set以外の方法を教えてくれているページがありましたので、参考に↓
[PHP]file_get_contentsのタイムアウトの制御とかレスポンスヘッダのバッドノウハウ

2011/11/15

jmeterでモバイルサイトのセッションを使う

スマートフォン移行が進んで、最近はずいぶん少なくなって来たのかもしれないけど、モバイル向けサイトでは、cookieが使えない機種に対応するため、URLにセッションIDを付けてページ遷移させることも多い

http://sample.com/?sid=***************

みたいなやつ。


こういう仕様のサイトをjmeterでテストする場合。
「HTTPクッキマネージャー」を使ってもセッションが切れてしまう。
セッションIDを前もって指定できれば楽なんだけど、それってできない…よね?
なので、リダイレクトなどするページを使ってセッションIDを取得する。
どこかリダイレクトするページを「HTTPサンプラー」で読み込む
リダイレクトされると、セッションIDがついているので、「正規表現抽出」でセッションIDを取得して、その後セッションを使うページを読み込む時にパラメータでセッションIDを追加すればOK。

[CakePHP] urlで渡されたクエリパラメーターの値を取得する

CakePHPでURLで渡されたパラメーターの値をコントローラーで取る方法

http://sample.com?value=100
↑の100って値を取得したい場合

$this->params
にいろんなパラメーターが入っている

URLで渡されたデータは
$this->params['url']
で取れる

上の場合だと
$this->params['url']['value']; //100


他にもう一つ
http://sample.com/10/12
みたいに値だけ渡すことも可能

その場合は

public function action($param1, $param2){
 //ここで処理
}
というふうにコントローラーのメソッドの引数で受け取れる

2011/11/14

[Android] Androidのuseragent一覧

Androidのブラウザはバージョンによって、細かく違いがあって、なかなか大変だ…
ある動画サービスを使ってみたんだけど、2.3だと動画が見れるけど、2.2だと再生できない。
もとの動画はmp4なので、再生できそうなんだけど、コントローラーが表示されない。

自前でコントローラー作らないとだめかもなー。

useragent switcherなどでAndroid用画面を見る用に、Androidのユーザーエージェントをまとめてくれてる人がいたのでリンク↓↓

参考:
http://team-pag.interprism.co.jp/member/noguchi/data/
http://pwiki.awm.jp/~yoya/?Android/UserAgent

2011/11/11

[JavaScript] スマートフォンでのselectのchangeイベントのタイミング

スマートフォンのフォームのselectタグのUIって選びやすくていい。
iPhoneだと画面下から選択項目がでてくるやつね。

で、それを変更した時のonchangeイベントのタイミング

iPhoneの場合
項目を選択して、決定を押した時


Android 2.3の場合
項目を選択した時 (決定?完了?ボタンを押す前)

なのでAndroidの場合、画面下部に選択項目が出てる状態でonchangeイベントが起きる。

「決定」を押した時のイベントはなんになるんだ?

2011/11/10

[JavaScript] 配列の中から最大値を取得する

phpのmax()みたいな関数が必要になったので調べてみたらあった。

var data = [3, 9, 1 , 4];
var max = Math.max.apply(null, data); //max = 9

applyってのは関数の中で第1引数をthisとして、第2引数を引数として処理してくれる。
Math.maxの中ではthisは使わないので、何でもいい。簡単なのでnull。
第2引数の配列を引数として処理するので、

Max.max(3,9,1,4);
と同じ処理になる


参考:【javascript】配列の値の中から、最大値、最小値を求める(配列を引数に展開する)

2011/11/08

[JavaScript] querySelectorAllなどで取得するNodeListと配列を判定する

jQueryなんかのライブラリを使ってる場合は必要ないかも…

自作でjQueryとかのeach関数みたいなやつを作った時にちょっとひっかかったのでメモ

instanceof Arrayだけで判定するとquerySelectorAllで取得できるNodeListはfalseになる。

配列 or NodeListを判定するには
if(valinstanceof Array || (val.item !== void 0 && val.length !== void 0))




ちなみに自作のeach関数みたいなやつ

var each = function(val, fnc){
  if(val instanceof Array || (val.item !== void 0 && val.length !== void 0)){


    //配列 or NodeListが渡された時の処理
  
    for(var i = 0, len = val.length; i < len; i++){
      //処理
      fnc(val[i]);
    }
  }else{


    //単数で渡された時の処理
    fnc(val);
  }
}

Twitter で複数の条件で検索した結果を表示する

最近、制作するページにTwitterを表示したいって話があった
できればハッシュタグでやりたかったんだけど、あまり使われんかった…

なので、複数のキーワードのどれかにひっかかった結果を表示することになった
やり方は…

キーワード1 OR キーワード2 OR キーワード3

って書くだけ。

参考:これだけは覚えておきたい、Twitter検索で使える便利なオプションまとめ

Twitterウィジェットでも同じように使えた
Twitterウィジェット

2011/11/04

[SQL] WHERE句ではSELECT句でつくったカラム名は使えない

深く考えたことなく使っていたので、言われてみれば、ああそうなんだという感じ。

SELECT句で命名したカラムはWHERE句で使えない

SELECT id, end - start AS diff
FROM table
WHERE diff > 3; //ここでエラー

↑だとエラーになる。

なんでかというと…
SQLには各句の解釈される順番があって
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY
という順序だから

WHEREでカラム名を指定しても、SELECTはまだ解釈されてないから、そんなカラムないよってことになる

上の例でいうと

SELECT id, end - start AS diff
FROM table
ORDER BY diff DESC;

は可能

考えたことなく使ってたなー


参考:

2011/11/02

[JavaScript] 配列かどうか判定する

JavaScriptで、ある変数が配列かどうか判定することがよくある。
判定は[ instanceof Array ]でできる


if(val instanceof Array){
  //配列だった場合
}else{
  //配列じゃなかった場合
}


渡された引数が単数でも配列でも同じように処理できるようにする時とか

function fnc(val){
  val = (val instanceof Array) ? val : [val];


  for(var i = 0, length = val.length;  i < length; i++){
     //処理
  }
}


querySelectorAllなどで取得できるNodeListも判定したい場合は「querySelectorAllなどで取得するNodeListと配列を判定する


参考:
JavaScriptパフォーマンス改善(3) オブジェクトが配列かどうか判定する方法

[JavaScript] 確認用のダイアログを出す

なぜかいつも忘れてしまうのでメモ

何かボタンなどをクリックした時に「○○してもいいですか?」というダイアログが出てきて、「OK」を押すと、その処理を行なって、「キャンセル」を押すと何もしないというアレ。

if(window.confirm(確認用メッセージ)){
  //OKの場合の処理
}else{
  //キャンセルの場合の処理
}


スマートフォンのダイアログの外観は味気ないものじゃないのでありがたい


参考:
確認ダイアログを表示する

2011/10/13

Zend Mail PartでメールのContent-typeが取得できない

あるサイトで、メールで記事などを投稿する機能を作った。
メールの解析はZend Mail Partを使ってる

メールのヘッダーにcontent-typeがないというエラーが出ることがある。

エラーが出た時点でのデコーダの解析した部分を見たら空っぽだった。

同じ内容のメールを送っても再現できない。
同じユーザーでもできる時とできない時がある。

いまのところ原因不明。
うーん…なんだろう。


- add 2012/5/2 -

再現することはできるようになった。
gmailで本文に日本語を使用せずにメールを送るとcontent-typeが取得できないというエラーが出る。

thunderbirdでgmailから送信したメール見てみる。
content-typeは…ある。
thunderbirdがメールのヘッダーを生成するんだろうか?

しかも実際にエラーが起きているメールは本文には日本語が使用されていた。
うーむ。

2011/10/12

[Android] JavaScriptで位置情報を取得するのにやや時間がかかる

JavaScriptで位置情報を取得するには

navigator.geolocation.getCurrentPosition(
  function(pos){
    //成功時
  },
  function(){
     //失敗時
  }
);


↑のコードで取れるんだけど、手元にあるAndroid2.3で試したところ、iPhoneに比べて位置情報の取得に時間がかかった。(体感だと2秒くらい)

体感速度を早めるためなどの理由で、位置情報の取得前に画面を動かしたりする場合は注意しないとな。

2011/10/07

[MooTools] 親要素・子要素・兄弟要素 取得方法まとめ

MooToolsでの要素取得方法

var $elem = $(id);




■親要素

1つだけ。条件が指定されていたら、さかのぼって条件に合う要素を取ってくる
$elem.getParent(条件);

全部取得 。条件が指定されていたら、さかのぼって条件に合う要素を取ってくる 
$elem.getParents(条件);




■子要素

1つだけ取得
$elem.getElement(条件);

IDで指定

$elem.getElementById(id)

複数取得
$elem.getElements(条件);


直下の子要素のみ
$elem.getChildren(条件);

最初の子要素
$elem.getFirst(条件);


最後の子要素
$elem.getLast(条件);



■兄弟要素

すぐ次の要素
$elem.getPrevious(条件);

後ろにある兄弟要素すべて
$elem.getAllPrevious(条件);

すぐ前の要素
$elem.getNext(条件);


前にあるもの兄弟要素すべて
$elem.getAllNext(条件);

参考:
MooTools ドキュメント日本語訳

iPhone, AndroidでURLバーを隠す

スマートフォンは画面が小さいのでURLバーを非表示にしたい時がある。
そんな時は

scrollTo(0, 1);


これでurlバーが隠れる。
縦のスクロールが0だとAndroidが反応しない

ページの高さが画面の高さより小さい場合はURLバーは出たまま。
スクロールできないからね。



-- add:
※ページ読み込み時に上の処理を無条件で動かすと、この処理が動く前にスクロールしてたのが、一番上まで戻されることになってしまうので注意。
スクロールされていない時だけに限定したほうがよさそう
if(docment.body.scrollTop === 0){
 scrollTo(0, 1);
}
参考:
iPhone/Androidブラウザのアドレスバーを隠す方法

jmeter内で条件分岐して処理を切り分ける

jmeter便利だなー

jmeterの処理中に変数の値やなんかの条件によって処理を分岐することができた。

やっている処理の項目を選んで右クリック→「上の階層に挿入」-.>「ロジックコントローラー」->「ifコントローラー」

これに条件を入れられるので、その条件がtrueの時だけ、その「ifコントローラー」の子の項目がテストされる。

参考:
IFコントローラの使い方

2011/10/06

[JavaScript] スマートフォンでJavaScriptの処理にかかる時間を計測する

最近のブラウザだと

console.time('test');
//処理
console.timeEnd('test');

で処理にかかった時間が計測できるんだけど、スマートフォンだとまだできない。




なんで、処理開始前と処理終了後の時間を比較して、処理にかかった時間を計測する

var startTime = new Date().getTime();


//処理


var endTime = new Date().getTime();

console.log(endTime - startTime);


2011/10/05

[WordPress] カスタム投稿タイプの一覧ページが表示されない

カスタム投稿タイプ別の一覧ページは
http://example.com/カスタム投稿タイプ名
でその投稿の一覧が表示されるんだけど、なぜかある投稿タイプの時だけ404になった。

結局理由はわからないまま…
今回はhas_archiveをtrueにすることで解決できた。

has_archiveをtrueにすると
archive-{post_type}.php
archive.php
index.php
の順にファイルを読みにいく。

構成によってはこのやり方だと対応できないかも


参考:
カスタム投稿タイプのメインインデックス(WP 3.1~)

メールヘッダーの解析でエラー


以前メールで記事を投稿するようなシステムの変更に関わった。
そのシステムは何年も前に作られたもので、携帯からの投稿を原則としてた。デコメールにも対応してた。

いつ頃からかそのシステムで時折エラーが出るようになった。俺が関わったのはその頃。
原因はiPhone。
iPhoneのメールヘッダーはそれまでの携帯のメールヘッダーと、違う箇所が結構あった。
色々解析しながらiPhoneメールには対応して、無事終了。

それが最近またエラーが出るようになった。
調べてみるとメールヘッダーにContent-Transfer-Encodingがあることを前提に処理していたので、Content-Transfer-Encodingがない場合はエラーになってしまっていた。

Content-Transfer-Encodingがない場合は7bitを指定したことになるみたい。知らんかった。

通常のiPhoneメールだとそういうことはなさそうなので、デフォルト以外のメールアプリから送信されたものっぽい。
色々増えてくると難しい…けど、コレくらいは予想しとくべきだったな、と反省。

2011/10/03

[JavaScript] data-から始まる独自の属性を取得する


HTML5から独自の属性を追加する際の名前の付け方にルールができた。
<div data-key="value">aiueo</div>
data-○○とつける。

この値をJavaScriptで取得する場合
elem.getAttribute(data-key);
でもできるんだけど、もっと簡単な方法が提供されてた

elem.dataset.key
で取得できる

仮に
<div data-id="100"></div>
の場合
var id = elem.dataset.id; //id = 100
で取得できる

data-○○-○○にするとjQueryとHTML5の仕様で違いが出てしまうらしいので、data-移行にはハイフンを使わない方がいいらしい。



>

2011/09/30

[jQuery] イージング一覧

jQueryのイージングの名前をいつも忘れてしまうのでメモ


linear
swing
jswing
easeInQuad
easeOutQuad
easeInOutQuad
easeInCubic
easeOutCubic
easeInOutCubic
easeInQuart
easeOutQuart
easeInOutQuart
easeInQuint
easeOutQuint
easeInOutQuint
easeInSine
easeOutSine
easeInOutSine
easeInExpo
easeOutExpo
easeInOutExpo
easeInCirc
easeOutCirc
easeInOutCirc
easeInElastic
easeOutElastic
easeInOutElastic
easeInBack
easeOutBack
easeInOutBack
easeInBounce
easeOutBounce
easeInOutBounce


実際の動きは↓↓を参考にしてください
参考
jQuery日本語リファレンス Easing/jQuery

2011/09/28

スケートボードもった選挙ポスター。選挙も滑りましたってか!



・スケートと選挙ポスターというミスマッチさ・意外性。意外性のあるものは目を引く

・スケートボードメーカーが会社としてやってるってのはびっくり。反発も考えるとリスキーだと思ったが、そもそも会社のターゲットは社会の良識派じゃないか。

・若者たちに選挙への興味を持たせるためじゃなくて、自分の会社へ興味を持たせたいんだよな。
そりゃ、スーツ姿のおじさんおばさんがボード持ってたら、スケーターは興味持つよな。

・スケーターの価値観ってのは具体的に知らんが、社会のアウトサイド側ってことで考えると、大人で、真面目くさった嘘つき達を相手にふざけるってとこが「クールだぜっ」って思わせられるんじゃないんかな

「うんうん、意外性を持たせることで興味を引けるんだな、わかった!」なんてタマキンみたいなしたり顔してましたが、じゃあ具体的にやってみろよって言われると、タマキンみたいな案しかでてこないっすね。
この人らはなんで意外性をもたせるやり方を選んだんかな。
うーん…面白いから…?

参考:
“選挙ポスター”を利用したスケボーメーカーのゲリラ広告

[jQuery] 指定した要素まで画面をスクロールさせる方法


フォームで項目が多くて、フォーム全体が1画面内に収まらなかった時に、フォームの先頭にエラー文を出して、その文をクリックするとエラーがあった項目までスクロールさせるという機能をつけたい。

どうやってその場所までスクロールさせるか
↓↓↓

var btn = $(".btn");
var target = 移動先の要素



btn.click(function(){
  $('html,body').animate({

    scrollTop: $target.offset().top}, {
    duration: 400,
    easing: "swing",
    complete: function(){
      //アニメーション後になにかしたいならここに書く
    }
  });
});
ウィンドウのスクロールはhtmlとbody要素のsrollTopの数値を変えるといい。

今回の場合は、エラーになっている項目を目立たせたかったので、その項目のタイトルに背景色をつけた。
アニメーション後にハイライトしたり、点滅させたりでもいいかも。

2011/09/26

[JavaScript] チェックボックスでチェックが入っている要素を取得する

css3で使えるようになった:checkedを使うと、チェックが入っている要素が簡単に取得できる。

docment.querySelectorAll("input:checked");

でチェックが入ったinput要素のリストが取れる。

cssでも指定できる
input:checked{
  color: red;
}

2011/09/25

PHPでファイルのURLから、そのファイルの有無を判定する

phpだとfile_exists($file)でファイルの有無判定できるけど、URLの場合はこれだと判定できない。
file_get_contentsでも判定できそうだけど、中身は必要ないって時ようの関数。
ファイルがあるか無いかの判定だけを返す

function url_exists($url){
  $header = get_header($url);

  //ヘッダーの中身から判定する


  if(preg_match('/OK$/', $header[0]){
   return true;
  }else{
    return false;
  }
}

2011/09/22

[WordPress] カスタム投稿タイプ別にカスタムフィールドを使い分ける

WordPressでサイトを構築して、更新を人に任せる場合は、入力項目の管理なんかが難しくなりますね。
カスタム投稿タイプができて、投稿ごとにカテゴリーを選んでもらうという作業が亡くなった分楽にはなったんですが、カスタムフィールドを使おうとすると、更新する人によってはハードルが高いこともあります。

投稿タイプごとに、表示するカスタムフィールドを切り分けることができれば、とりあえず、出ている項目に必要なデータをいれて投稿すればOKって感じにできそうです。

Custom Field GUI Utility 3 - WordPress プラグイン

昔からずいぶんお世話になってるプラグインです。
投稿タイプってのができたことに対応して、投稿タイプごとにカスタムフィールドの表示・非表示を切り分ける機能がついたらしい。

ありがたや、ありがたや。

2011/09/21

[JavaScript] スマートフォンかPCか判別する

正確には、タッチパネルかどうかを判定する機能。
これからノートパソコンにもタッチパネルとか出てくるかもしれないから、確実じゃないかも。

var clickType;
var hasTouch;

if("ontouchend" in window){
  hasTouch = true;
  clickType = "touchend";
}else{
  hasTouch = false;
  clickType = click;
}


こうやってタッチパネルかどうか判断しといて、クリック(またはタッチ)イベントには

element.addEventListener(clickType, function(){
  //ここに処理
});


touchendイベントの設定だけだと、タッチした後、ドラッグアウト(でいいのかな?)した時でもイベントが起きるようになるので注意。
必要ならtouchmoveが起きた時はイベントが起きないようにしないとだめ

詳しくは「iPhone、アンドロイドでのクリックイベント

2011/09/16

HTML5ではscriptタグもlinkタグもtype属性は必要ない

いつも忘れてしまうのでメモ

HTML5ではscriptタグもlinkタグもtype属性は必要ない

<script src="javascript.js"></script>
<link href="css.css" rel="stylesheet">

参考:
HTML5タグリファレンス
link 要素

2011/09/15

[JavaScript] スマートフォンでウィンドウの高さを取得する

スマートフォンでウィンドウの高さを取得するのは簡単…なはず。

window.innerHeight;

これで一応取得できる。

困るのはURLバーが表示されている時とされていない時で数値が変わってくること

URLバーが出てる場合は

実際のウィンドウの高さ - URLバー
が返ってくる。

要はコンテンツを表示する部分のサイズってことなんだけど、動的にサイズを決めたりする場合はメンドくさいこともある。

scrollTo(0, 0);//スクロールさせてURLバーを隠す
var windowH = window.innerHeight;


こんな感じにすればURLバーがない場合で統一できる


参考:
スマートフォンサイトのディープな作り方

2011/09/09

iScrollを設定した要素が非表示の時に、画面を回転させて向きを変えるとうまく動かなくなる

スマートフォン向けサイトでiScrollを使ってるんだけど、iScrollを適用させてる箇所がデフォルトでは非表示になってる。
ボタンをクリックすると、そこが表示されるって感じ。

非表示中は高さをうまく取得できないらしく、非表示のまま画面を横向きにした後、iScroll部分を表示させるとうまく動かない。
iScrollには設定を更新するrefreshというメソッドがあるのでそれを使う

var iSc = new iScroll(wrap);

setTimeout(function(){

  //iScrollの要素を一旦表示にする
  wrap.style.display = "block";
  //iScrollの中身を更新
  iSc.refresh();
  //表示を戻す
  wrap.style.display = "";
}, 0);


これを画面回転時のイベントで呼び出す


ちょっと前に「css切り替えたのに表示がかわらん!」っての書いたんだけど、色々変更しているうちに治ってた…。
原因調べとかないとな…

2011/09/08

[WordPress] ファイル名を指定して、画像パスを取得する

WorePressにはアイキャッチ画像って便利な機能あるけど、1枚しか設定できないから、物足りないときがある。
各記事に、決まったタイプの画像を複数掲載する場合など…
例:メイン画像とサブ画像とタイトル画像を記事に使ってるとか
メイン画像をアイキャッチに登録した場合、他2つはどうするか?
カスタムフィールドに登録してもいいけど、その場合はサイズを指定して取得したりするのが難しくなる(っぽい。)

なんでその記事に登録されている画像からファイル名を使ってパスを取得する方法を考えた



function getImgByName($post_id, $name, $size = 'thumbnail'){

  //その記事に登録されている画像を全部取得
  $files = get_children('post_parent=' . $post_id . "&post_type=attachment&post_mime_type=image");

  foreach($files as $key => $file){

    //ファイル名だけ取り出す
    $path = explode("/",$file->guid);
    $path = end($path);

    //ファイル名取得する関数あったね
    $filename = basename($file->guid);


//ファイル名を調べて、指定したものだったらそのimgタグを返す
    if($name === $filename){
      return wp_get_attachment_image($key, $size);
    }
  }
  return false;
}

function.phpに追加すれば、テンプレでは
<?php echo getImgByName($post->ID, 'title.png'); ?>
みたいに使える

2011/09/05

[iPhone] css切り替えたのに表示がかわらん!

タッチする毎にクラスを切り替えて背景色を変えるって処理をしてたページにiScrollを設置したら、iPhonで見ると、タッチしてから背景色が変わるまでにすごく時間がかかるようになった(体感で4秒くらい)

なにもしないとそれくらいかかるんだけど、画面をタッチするとすぐ表示が切り替わる。
でも、再度タッチした分の表示は変わらない。

どうやら描画するタイミングがおかしくなっているみたい。

スクロールしないページだったので、
scrollTo(0, 0);
で描画を更新するようにした。
対症療法だけど…

原因はわからず…

[JavaScript] スタイルの値を取得する

element.style.***だとcssファイルで設定している値が取得できない。
この場合はgetComputedStyleを使う

var styles = getComputedStyle(取得したい要素, 疑似要素);

第二引数の疑似要素」は指定しない場合は、空の文字列を渡す

2011/09/02

[JavaScript 高速化] 初期設定やなんやかんやもイベントが起きるまでやらん!

参考にした記事が2007年と2008年のものなので、今では古いテクニックなのかもしれんけど…

最近、スマートフォン向けのサイトを作った。
PC向けと比べてネットワークが細いのと処理速度が遅いことを考えて、より高速化に対してシビアにならんといかん。

で、ボタンをクリックしたら、画面下からシュッとモーダルウインドウが出るような機能をつけた。
そのモーダルウィンドウ内でも、あれやこれやと機能がついてる。
でも、そのボタンは押されないかもしれないっていうサブ的な機能。


この機能の設定をJavaScript読み込み時にやっても使われなかったりする

なので、できればボタンがクリックされるまで、機能設定も動かないようにしていたい。

要は最初の1回だけ初期設定機能を付けて、2回目以降はそれを動かさないようにしたい。

パッと思いつくのが↓(ダメパターン)
var flag = false;
var kinou = function(){
  if(flag === false){
    //初期設定処理

    //フラグを切り替え
    flag = true;
  }

  //通常の処理
}

まあ、これでも動くんだけど、flagって変数が必要になるのと、関数呼び出すたびに条件判定をする必要がある。
こんなときには「Lazy Function Definition Pattern」
直訳すると「怠けた機能の定義様式」

var kinou = function(){
  //初期設定処理をここに書く

  //ここで関数上書き
  kinou = function(){
    //通常処理
  }

  //通常処理を起動
  kinou();
}

1度関数が呼ばれると、初期設定をする。
その後、関数内でその関数を上書き。初期設定機能はなくなって、通常機能のみの関数になる
2回目以降は、通常機能のみが動くようになる

「関数の外の変数を見にいかなくなる & 条件分岐がなくなる」より高速になるってことね。

「高速化」じゃなくて「早漏化」っていってみるととたんにやる気がなくなる。


参考:
JavaScriptの動作を軽くするための工夫
Lazy Function Definition Pattern(英文)

2011/09/01

[Linux] サーバーの負荷を調べる

サーバーの負荷を調べることは多いと思う。
サイトが重いとか、cronで重い処理を定期的に動かしているとか。

・topコマンド
現在のシステムの状態を表示する
5秒おきに表示が更新される

・uptimeコマンド
cpuの負荷が見れる

・sarコマンド
管理者向けのいろんな情報が見れる
さかのぼってデータを見ることができる

参考:
top - システム情報をリアルタイム監視 | Linuxサーバ監視
uptime - システムの稼動期間・平均負荷調査
sarコマンド - CPU・ネットワーク・メモリ・ディスク情報確認

2011/08/30

.htaccessで特定のIPアドレスのみアクセスを許可する

会社や自宅などの特定の場所からのアクセスは許可して、そこ以外の場所からのアクセスにはBasic認証をかけたいということがあった。

すごく参考になるページがあったのでメモ。
BASIC認証とIPアドレス制限の併用


まずは全文。

AuthType Basic
AuthName "Please enter username and password"
AuthUserFile htpasswdへのパス
AuthGroupFile /dev/null
require valid-user



Order Allow,Deny
Allow from 「特定のIPアドレス」
Allow from 127.0.0.1


Satisfy Any




これを分解していくと

Order Allow,Deny
これで一旦すべてのアクセスを拒否してる

Allow from 「特定のIPアドレス」
Allow from 127.0.0.1

これで特定のIPアドレスからのアクセスのみ許可する。
127.0.0.1とは、自分自身を指す特別なアドレスのこと

ちなみに

Allow from all //全部
Deny from example.com //ドメイン名で指定


という指定方法もあるらしい


Satisfy Any

これはID/Pass制限とアドレス/ホスト名で制限の両方が設定されている時にの動作を決めている


Satisfy Any
だったらどちらか片方

Satisfy Alll
だったら両方とも条件を満たす必要がある


参考:アクセス制限の記述(Order, Allow, Deny)

2011/08/25

自動でサイトのテストをしたい

JMeterっていうアプリケーションがあります。
サイトの負荷テストをするためのアプリケーションです。

作成したページの表示は1人でも確認できますが、実際に本番で多くのユーザーがアクセスしてきた場合はどうなるのかってのは1人では調べづらい。
JMeterってのは、本番の様にサイトに負荷をかけつつテストすることができるアプリケーションのようです。

今のところ僕は負荷テストではなく、サイトのページの確認用に使ってる。
たとえば、webアプリケーションのシステムを大きく変更したとか、共通で使用している部分を変更したって時に、思わぬとこでエラーが出たりする。
それを1人で全部チェックするってのは難しい&馬鹿らしい。

JMeterってアプリケーションに確認したいページをすべて登録しておいて、エラーが出ていないかどうかを判定してる

使い方などを詳しく掲載している記事があったのでどうぞ
JMeterでWebアプリケーションのパフォーマンス測定を行う

2011/08/22

[Symfony] layout.phpを変更する

使用するレイアウトファイルをデフォルトのlayout.phpから変更したい場合は、アクション内で
$this->setLayout('new-layout');
とすればいい

↑の場合はアプリケーション/template/new-layout.phpを使用するようになる

ウェブアプリの高速化

実践・ウェブアプリ高速化テクニックという記事を読んで思ったことをメモ。

上記の記事の要点
・高速化とはプログラムの処理スピードなどではなくUser Experience!
・ユーザーが快適にサービスを利用できているかが重要
・快適→ユーザーが起こしたアクションへの迅速なレスポンス。実際の速さよりもユーザーが速いと感じることが重要
・Gmailのスターはローディングも出さずに反映する

高速化を考える際に、ユーザーのことを忘れているというのは同感。自分もよくそうなる。
処理速度をあげるってのは、計測できるという点からすると、けっこう楽。
やり方によって実際に処理にかかる時間が目に見えてへっていくからね。

それに比べて、ユーザーがどう感じてるかを考えながら作るのはなかなか大変。
作っているこっちは何十回、何百回と同じことをくりかえしたりするので、もう感覚がわからなくなったり、秒数を減らすのと違って、どういうふうにすれば快適だと感じるかというノウハウを持っていなかったりする(俺の場合ね)。

重要なのは何かしらのレスポンスの速さってことかな。

・オンマウス時のリアクション
・クリック時のリアクション
・ローディング時のリアクション

まずは一瞬でもレスポンスがないような状態をなくす。

・ローディング時のプログレスバー・読み込み完了度の表示
これはただ「Loading...」とか出ているのとは気持ちはかなり変わる。
いつまでかかるかわからないような処理は待ってもらえない。

・エラー時のリアクション
なぜエラーが起きたのかが明確に伝える
エラーの解決方法を伝える

他にも色々ありそうだなー

2011/08/19

MVCのお勉強。太ったモデルと痩せたコントローラ

下の2つの記事を読んで、すこし理解が深まったような気がしているのでメモ
Web アプリの MVC 設計まとめ :: もやし日記
えせMVCについてそろそろ一言言っておくか :: ひがやすを blog

CakePHPを使ったMVC設計のベストプラクティスを読んで、ビジネスロジックはモデルに置くべきだと認識した。コントローラーをシンプルにしておけば処理の流れもわかりやすいだろうと。

特定のモデルに大量のメソッドが集中したり、どのモデルがどういうトランザクションを担当するのかが分かりにくくなってきて、コードの可読性は下がり、重点的にテストすべき場所も分かりづらくなってきます。
Web アプリの MVC 設計まとめ :: もやし日記
確かに機能が増えてモデルが多機能になりすぎることはありそう。
実際1つのカラムの値を取得したいだけなのに、多機能なインスタンスを作らないといけないってのもメモリーの無駄遣いかも。
あるコントローラでしか使われていない機能があるってのも気になる。

次の間違いは、Skinny Controller, Fat Modelが最良だと信じている点。
Fat ModelはFat Controllerと同様にテストはしにくいし、理解しづらくなる。ロジックはそれぞれ適切なところで実装すべきで、Fatなのはやはりよくないのです。
えせMVCについてそろそろ一言言っておくか :: ひがやすを blog

ふむふむ。やはり過ぎたるは及ばざるが如しですな、と脳みそ停止しきってるくせに理解したふりしてみる。
コントローラーとモデルの両方をテストしないと確実じゃないってことになったら、そのテストってなんなの?って感じはするな。


追記:一昔前のフレームワークなら、ControllerはWebのAPIに依存していてテストしにくいというのもあってControllerからロジックを追い出せということがよく言われてきましたが、いまどきのちゃんとしたフレームワークは最初からControllerもテストできるように考慮されています。
えせMVCについてそろそろ一言言っておくか :: ひがやすを blog

そもそも、コントローラーにロジックを置かない理由の1つがテストしづらいからだったの?
他にはどんな理由があるんだ?コントローラはロジックを置くとこじゃないってのが1番の理由だと思ってたんだが…どうなんだろう。

きっちりテストできるならどこにあってもいいってことなら、それはそれでシンプルな考え方でいいかも。で、実際にそうしてみたら、テストのやり方が煩雑になって、やっぱりどっかにまとめようぜってなりそう。

今日の俺POINT
・基本コントローラーはシンプルに。
・Fat Modelには気をつけよう
・なんでもFatは良くないよ
・Serviceってやり方もあるらしい
・2008年と2009年の記事なんで、今は変わってるかもしれん。

コントローラにたった1つだけあるドクロマークのボタンを押すと、太ったモデルがセクシーに踊りだすという解釈でいいであろうと思われる。

2011/08/09

[cakePHP] MVC設計ってまだ把握できとらん…

CakePHPを使ったMVC設計のベストプラクティスを読んで、一度読んだだけではなにがどうなったのかよくわからんかったので、自分なりにまとめてみた。


■コントローラーが変更された点
・共通したorder指定を抜き出してモデル側で設定
・データを取得して表示するという流れは同じなので、アクションを1つにまとめた
・件数指定部分をモーフィングっぽく配列に格納
・モデルにオプションを渡して取得できるようになった
・渡されたパラメーターによって自動で処理が変わるようになった


■モデル
・並び順のデフォルト設定追加
・人気順で取得する機能追加
・特定の設定はモデル側でもっとく



■要点
・MVCではモデルが一番大事
・コントローラーはモデルとビューをつなぐシンプルな糊
・モデルに置けるものはモデルに置く
・ビジネスモデルと連携しないもの(セッション管理・リクエスト、レスポンス処理・セキュリティ、アクセス制限関連)はコントローラーに置く。(それ以外は全部モデルに置く)



参考
CakePHPを使ったMVC設計のベストプラクティス

[symfony] コントローラー内で共通の処理をまとめる

symfonyのコントローラーにはpreExecute()とpostExecute()というメソッドがある。
preExecuteはexecute~の前に、postExecuteはexecute~の後に処理が行われる。
ここに処理を書けば、コントローラー内のアクションに共通の処理を行える

public function preExecute()
{
  parent::preExecute();


  //やりたい処理
}

共通でやりたい処理をどこかにまとめとく機能もたぶんあるよね。cakePHPのビヘイビアみたいなやつとか

2011/08/05

iPhone, Android などのスマートフォンでJavaScriptエラーをデバッグする

スマートフォンのJavaScriptのデバッグはなかなか大変。

■iPhone
iPhoneはわりと楽。
「設定」 -> 「Safari」 で「デベロッパ」をONにする
でも、エラーやconsole.logの詳細は教えてくれない。
今はMacと繋げれば、Mac側のsafariから色々情報が得られるようになった。便利。

■Android
残念ながら、端末にはデバッグ機能はなし
シミュレーターのlogcatってやつを使えばログも見れる
windowsなら
adb logcat | findstr browser
でブラウザ絡みのログだけに絞れる

参考
Androidシミュレーターのインストール



■サーバー側にログを残したい

上の方法だと、ちょっと物足りないのでJavaScriptでエラーがあった場合はサーバー側に通知するようにもできる
window.onerrorにJavaScriptエラーの場合の処理を書けばいい
引数にはエラーが起きた行数なんかもくるけど、IEの場合、あまり信頼できないらしい…

window.onerror = function(messsage, url, line){
  //ここに処理
}
俺の場合は、urlにエラーに関する情報をくっつけて、ajaxでページを渡して、読まれたphp側でログファイルに出力することにしたけど、より簡単そうなやり方がWeb+DB PRESS vol.63に紹介されてた

window.onerror = function(message, url, line){
  var param = "?message=" + encodeURIComponent(message)
    + "&url=" + encodeURIComponent(url)
    + "&line=" + line;

new Image().src = "error_log.gif" + param;
}
まあ、この場合もダミーのgif画像を用意しつつ、いろいろ処理はしないといけないだろうけど、読み込む方法としては楽そう



[JavaScript] DOMのタグ名を判定する

DOM要素のタグによって処理を分けたりすることがあります。

if(div.tagName.toUpperCase() !== "DIV"){
//処理
}

ブラウザによって返ってくるタグ名が違ったりすることもあるので、toUpperCaseで大文字に揃えてる

2011/08/03

[cakePHP] モデルのルール

-クラス
必ずAppModelを継承して作成する

-モデル名の定義
public $name = 'モデル名';
モデルの名前を定義する
単語の頭文字は大文字

とりあえずはこれだけでAppModelにあるいろんな機能が使える

AppModelは/cake/libs/model/app_model.phpにある
中身は空っぽで、ここに追加した機能は、コレを継承する全モデルで使えるようになる。
一部のモデルでしか使わない機能はここに入れたらダメだね。

一部のモデル用に共通で使える機能はビヘイビアってを使うのがいいみたい

参考
モデル :: CakePHPによる開発 :: マニュアル :: 1.3コレクション

[Symfony] propelでgroup byする

なぜかいつも忘れるし、そもそも出来ないんじゃなかったけ?っという勝手な思い込みが発生してしまうのでメモ

propelでgroup byするには
$criteris->addGroupByColumn(カラム名);


group by して それぞれにcountするのが面倒だったはず
GROUP BY して グループごとのCOUNT を取る

[cakePHP] レイアウト・テンプレートに実行したSQLを表示する

cakePHP 1.3でやってます

まずはアプリケーションのデバッグモードを変更する
/app/config/core.php内の
Configure::write('debug', 0);

Configure::write('debug', 2);
に変更する。
これでテンプレートにSQLが表示されるようになる

■レイアウトを変更したい場合。
デフォルトのレイアウトを変更したい場合は、/app/views/layouts/にdafault.ctpを作成すればよい。

実際そうしてみると、デフォルトの時は出ていたSQLがでなくなった
その場合は自分で作ったdefault.ctpに
$this->element('sql_dump');
を追加する。


参考
CakePHP での実行した SQL の表示

2011/08/02

[cakePHP] テーブルにprefixをつけている場合の外部キー・カラム名

cakePHPで外部キーを作成する場合、カラム名には制約がある。(制約以外の名前でも使用することはできる)

マニュアルより::
現在のモデル名のアンダースコア区切りの単数形で、末尾に‘_id’をつけたものです

今回、データベースの設定でテーブル名に接頭辞をつけるようにしていた。
mmm_usersテーブルとmmm_profilesテーブルを関連付けたい。

こういう場合も外部キーにするカラム名には接頭辞であるmmmはつけない
mmm_profiles.user_id
にする

2011/07/28

[Android] Android バージョン2.*ではクリックイベントの判定が遅い

Android2.*ではtouchendからclickまでの時間がちょっと長いようだ。
それで少しはまった。

TwiiterみたいにAjaxで読み込みながらどんどん縦に長くなるページで、ページの下の方まで進んだ時、スマートフォンではページのTOPに戻るのがけっこう面倒だった。(すごいスクロールすれば戻れる)

まあ、これは使用者に優しくなかろうと思って、Ajaxで読み込む度に「このページのTOPに戻る」ボタンを設置していた。
このボタンそれぞれにイベント設置しとけばいいんだろうけど、何ページも読み込むとボタンがいっぱい出てくるし、Ajaxで読み込むたびにボタンにイベント設置するのもなんか無駄が多そうだなと思ったんで、jQueryのデリゲートみたいに、枠全体にtouchendイベントを設置して、戻るボタンがタッチされた場合はページTOPにアニメーションで移動するようにした。

iPhoneではOK。Android3.*でもOK。
でもAndroid2.*では戻るボタンをクリックして、ページトップまでアニメーションしている途中に別のページに移動してしまう時がある。

調べてみると、touchendでスクロールが開始した後にclickイベントが起きて、どういう判定かわからんが、たまたまクリックしたと判定された場所がリンクの上だったりすると、そのリンク先に移動してたみたい。

他のバージョンでは起きないことだったから少し時間かかってしまった

【追記】
これってontouchendじゃなくてonclickで動くようにするだけで解決できたっぽいぞ…

2011/07/25

[MySQL] 外部キーに設定されているカラムを主キーに設定する

テーブルの主キーを変更する必要があった時に、ちょっとはまってしまったのでメモ

はじめ、1つの外部キーを主キーにしていた。
テーブルにあるもう一つの外部キーも主キーにして、複数の主キーを持つテーブルにしたい

いったん主キーを削除して再設定しようとして
ALTER TABLE table DROP PRIMARY KEY;
これがエラー。
外部キーだからか?

それでは、新しく主キーになるカラムを設定しようとして
ALTER TABLE table ADD PRIMARY KEY (id);
とするとエラー
Multiple primary key defined

結局、どっちのカラムも一旦外部キーを解除してから主キーに設定することで解決した。
主キー設定後、また外部キー設定をした

外部キー解除
ALTER TABLE テーブル名 DROP FOREIGN KEY 外部キー名;
外部キー名は
SHOW CREATE TABLE テーブル名
で見られる

主キーの登録
ALTER TABLE テーブル名 ADD PRIMARY KEY (カラム名[, カラム名2]);

外部キーの再登録
ALTER TABLE テーブル名 ADD FOREIGN KEY (カラム名) REFERENCES 参照先のテーブル名(参照先の主キー名);

[cakePHP] selectタグでデフォルトで選択する項目を指定する

[cakePHP 1.3の話 ]

フォームのselect要素を作成したい場合は

//コントローラー
$this->set('list', $this->Model->find('list'));

//ビュー
$form->select('Model.fieldname', $list);

でできるけど、このselectの項目の1つを選択状態にする方法がわからなかった。

見つけた方法は
$form->input('Model.fieldname', array(
  'type' => 'select',
  'options' => $list,
  'selected' => 選択したいアイテムの番号を指定
));

「選択したいアイテムの番号を指定」ってのは…
find('list')で取得したデータは

array(
[1] => 'hello',
[3] => 'good bye'
);
という風にキーがそのテーブルのIDになってくるので、このIDのことです。

2011/07/21

[JavaScript] onloadよりも DOMContentLoadedを使おう

window.onload = function{....
って書き方をよくするけど、コレだとHTMLだけでなく、画像の読み込みまで完了しないとイベントが起きない。

document.addEventListener("DOMContentLoaded", function(){...

で書くとHTMLの解釈が終わった時点で、画像の読み込みを待たずにイベントが起きる。
使えないブラウザもあるみたいなので注意

参考
これでできる! クロスブラウザJavaScript入門



[JavaScript] スマートフォンでのtouchendで指が要素の外でも反応してしまう

スマートフォンのclickイベントは、シングルクリックかダブルクリックかの判定をするために、0.数秒処理を待つので、体感的にもっさりとした感じを受ける。

なので、clickではなくtouchendイベントでいろんな処理をしていくんだけど、touchend時にターゲットの要素の外でもイベントが起きちゃって困った。

具体的には
ボタンの上に指をON。touchstartイベント
指を動かして、指をボタンの外に出す。touchmoveイベント
ボタンの外で指をはなす。touchendイベント
これで、ボタンに設定していたtouchendイベントが動き出す。

使う側としたら、スクロールやスワイプ?フリック?なんかをしたつもり なのに、なんか動き出したって感じかな。

この違和感をなくすために、指を動かしたら、touhcendイベントは起きないようにした。

var startY,
      endY;
 
function touchStart(e){
  //最初に触った位置を記憶
  startY = endY = e.touches[0].pageY;
}
               
function touchMove(e){
  //動いている間指の位置を記録
  //最後に触った位置で変数の値が決まる
  endY = e.touches[0].pageY;
}

function touchEnd(e){
  //iPhoneでは10ピクセルほどあそびがあって、それ以上動かさないと移動したと判定されない
 //Android2.1だと15ピクセルくらい
  if(Math.abs(startY - endY) === 0){
    //処理
  }
}

target.addEventListener('touchstart', touchStart);
target.addEventListener('touchmove', touchMove);
target.addEventListener('touchend', touchEnd);




touchendでendYを取得しないのは、Androidのバージョンによっては、touchendでevent.touchesが取得できなくなるから
動かした距離によって処理が変わったりしないならtouchmoveイベントが起きた時点でisMoved=trueみたいにフラグをたてると良さそう

2011/07/19

[JavaScript] Androidで touchend時に touchイベントが取得できない

Androidのバージョン2.2、2.3で起きた問題。

function touchend(event){
  event.touches[0] //undefinedになる
  event.touche.length //0
}

バージョン2.1までは取得出来ていたのに。
2.1以前で作っていたサイトは2.2でtouchendイベントが取得出来なくてうまく動かなくなってるかも

俺のやってたのは指の位置を取得する処理だったので、


var endX = 0;

function touchstart(event){

  //触った時点で値を格納
  endX = event.touches[0].pageX;
}

function touchmove(event){
  endX = event.touches[0].pageX;
}

function touchend(event){
  //endXを使った処理
}

↑みたいな感じでtouchmove中にずっと位置を取得し続けて、最後に格納された値で位置を判断することにした。

バージョンによって、ちょこちょこ動かなくなる箇所がある。
そしてこれからバージョン3以降もテスト開始...

2011/07/17

[cakePHP] htmlヘルパーまとめ

■リンクを作成する
$html->link(リンク文字列, url, 属性);

■画像を表示
$html->image(画像パス, 属性);

随時追加していきます

2011/07/15

[cakePHP] コントローラーでのルール

コントローラーはAppController を継承する
※間に1つ別のクラスを挟んだりしてもいいんだよな、多分…

-名前の定義
public $name
コントローラ名を定義する。1文字目は大文字。パブリックにする

-モデルの定義
public $uses = array('Table');
使うモデルの定義
そのコントローラーで使うモデルを定義しておく。
省略した場合は、コントローラー名の単数形のモデルを使う。
1つのテーブルしか使わないってことはそんなにはないよね?

-アクションの定義
function index(){}
メソッドとして登録
アクセスするURLは「/コントローラ名/アクション名」になる
省略した場合はindexアクション
php4の時は、メソッド名の最初を_(アンダースコア)で始めると、URLで指定してもアクセスできなかったみたい。
俺のとこはPHP5なんでprivateにしとけばいいんだろうけど。アンダースコアはいるのかな?試してみよう

-変数をビューに渡す
$this->set(変数名, 値)


cakePHP1.3からはfindAllはなくなったみたい。
find('all');で同じ動きになる

参考
CakePHPで作るToDoアプリ(1)

[cakePHP] cakePHPのデータベース、テーブルのルール

・データベース(以下DB)のテーブル名は複数形にする

・テーブルの主キーのカラム名はid

・作成日時はcreated、更新日時はmodifiedにする
※この名前にしておくと、自動で更新してくれる。

・外部キーに使用するカラム名は「関連付けたいモデル名」_id
※データベースの設定でprefixを付けていても、外部キーはprefixを無視してモデル名_idでつける


どれを単数形にして、どれを複数形にするかはすぐわすれてしまうなー

2011/07/13

[JavaScript] 要素を追加する

■子供要素を追加する方法

appendChildだと親要素の最後に子要素を追加できる

elem.appendChild(childElem);


先頭に追加したい場合はinsertBeforeを使う
insertBeforeは指定した要素の前に、新しい要素を追加できる

parent.insertBefore(追加したい要素, 既存要素);



なので先頭に追加したい場合は

parent.insertBefore(追加したい要素, parent.firstChild);


これで現状の最初の子要素の前に新要素を追加できる



■指定の場所に追加する

指定の要素の前に追加できる

node.insertBefore(elem);



参考
 [JavaScript] DOM Nodeに子ノードを



2011/07/12

JavaScriptで位置情報を取得する

スマートフォンサイトで位置情報を取得する処理があった。
コードはこんな感じ
if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(function(pos){
    //取得成功時の処理
  }, function(){
    //エラー時の処理
  });
} else {
  error('not supported');
}

iPhoneではうまく動いたのに、Androidでは動かないけど、エラーも出ない。
確認してみるとnavigator.geolocationは確かにある。

調べてみると、Androidの設定によっては位置情報を取得できないみたい。
「設定」→「位置情報とセキュリティの設定」の中の「無線ネットワークを使用」と「GPS機能を使用」の両方にチェックを入れたら反応するようになった。
デフォルトで反応しないとなると、位置情報を使ったサービスを使わせるための引きこみが必要になるなー

※試したのはXPERIA SO-01B(Android 2.3)ってやつ。他人のもの(2人にお願いした)だったので、詳細はわからないけど、2人ともGPS絡みの設定はやったことないとのことなので、工場出荷状態だとGPSは反応しないみたい

2011/07/06

[JavaScript] 親要素・子要素・兄弟要素の取得方法

JavaScriptでの要素の取得方法。ライブラリばっかり使ってると忘れてしまうので

■親要素

element.parentNode


■子要素

子供一覧
element.childNodes //NodeListオブジェクトが返ってくる
※子要素がない場合でも、空っぽのNodeListオブジェクトが返ってくる

最初の子
element.firstChild

最後の子
element.lastChild


■兄弟要素


兄ちゃん要素
element.previousSibling

弟くん要素
element.nextSibling

改行なんかもTextノードだと認識されるので、注意




jQueryでの取得方法もまとめてます
jQuery親要素、子要素、兄弟要素取得のまとめ


参考
ノード木を探索する



2011/07/05

[iPhone] CSSアニメーションがちらつく場合

iPhoneでCSSアニメーションを使う場合、画面がちらついてしまう時がある。

俺の場合は、位置を移動させるtranslateXを-webkit-transitionでアニメーションさせようとした時に起きた。

Androidでは起きない症状。
translateXの指定をtranslate3dに変更することでちらつきはなくなった。

-webkit-transform: translateX(100px);

↓↓↓ 変更 ↓↓↓


-webkit-transform: translate3d(100px, 0px, 0px);


参考
スマートフォン制作のツボ最新を聞いてきた-CSS Nite,LP13

[iPhone] アニメーションは CSSでやるべし

iPhoneのアニメーションをJavaScriptでアニメーションすると非常にもっさりとして、コマ落ち気味の乙な動きになってしまうので、CSS3の-webkit-transitionを使用しようしようしよう。

イージングの種類が少ないのが残念だけど、動きの滑らかさはJavaScripとは比べ物にならない

参考
CSS3 変形処理を行う transform プロパティ

2011/06/30

[JavaScript] Androidではwindow.history.pushState/replaceStateが使えない

結論から言うと、タイトルそのまま。Androidではwindow.history.pushStateが使えなかった。
もちろんreplaceStateも

スマートフォンサイト向けにTwitterのサイトでやってるように、ページ下部に表示したいデータをどんどん追加していくやつをやった。

追加して表示するのはAjaxでよみこんでinnerHTMLで後ろに追加ってのでできたんだけど、Twitterと違って、そのリストからそれぞれの個別ページにリンクしてた。

で、リンク先のページを開いた後、戻るボタンでリストページに戻ってみると、ページの一番頭に戻される。
それだとリストの下の方のをクリックしていた場合、またそこら辺まで表示させるのがめんどくさいので、ページを移る時にwindow.history.replaceStateでページの履歴を#付きのURLと入れ替えようと思ったんだけど、Androidではできなかった。iPhoneではできたんだけどなー。
(#に読み込んだページ数でも入れて、#が付いている時はリストのそのページを表示するようにしたかった)

location.hash = "page="+pageId;

で履歴に残すことはできた。けど、これだと#なしのURLと#つきのURLの両方が履歴に残る。
それもちょっと気持ち悪いような…

Androidの戻るボタンはブラウザの戻るとは違うからなのかな

2011/06/28

[JavaScript] HTML5のカスタム属性を取得する

HTML5から属性を拡張できるようになったみたい。
具体的には
<li data-type="loop-article">
とか
<input data-next-id="100">
とかいう風に、こちらで持たせたい属性を追加できる。
これはすごいありがたい

で、JavaScripでの取得方法。
element.getAttribute("属性の名前");

いたって普通。

[JavaScript] Domの作成・削除

jQueryなんかのライブラリを使っていると、JavaScript自体の関数を忘れてしまうのでメモ。

DOM要素を作るのは
document.createElement("div");
HTML5を使うときに、新しい要素に対応していないブラウザ対策で使うよね

DOMを削除する時は
var target = document.getElementById("delete-target");
document.removeChilde(target);

これは引数に削除したいDOM要素を渡す。
ターゲットになる要素自体はなくならないので、
document.appendChilde(target);
↑これですぐ戻ってくる

もちろんdocumentからじゃなくても指定できる
var container = document.getElementById("container");
var target = document.getElementById("delete-target");

container.removeChild(target);


参考
DOM 要素の生成、削除

2011/06/24

[Linux] 決まった時間にプログラムを自動で実行させる cron

サーバーのバックアップみたいに定期的に自動でプログラムを実行させたい場合にはcronを使う。


cronの表示
crontab -l


cronの編集
crontab -e


データベースの不要なデータやサーバー内の不要なファイルを削除するクリーンアップ用のプログラムを自動で毎日実行するってことになった。
通常通り指定するなら


0 6 * * * /home/sites/example.com/db_clean.sh
これで朝6時に実行される。
だけど、今回は6時からデータベースとサーバーのバックアップ処理がcronで設定されていた。
バックアップと削除の作業がかぶると大変なことになりそうなので、バックアップが終わってからクリーンアップを始めたかった。


なのでクリーンアッププログラムの最初でバックアップ作業がまだ動いてるかどうか判定してから処理を進めるようにした


cronの設定はこんな感じ
*/10 9-13 * * * /home/sites/example.com/db_clean.sh
9時~13時の間で10分おきにクリーンアッププログラムを実行してみる
バックアップが終了していたら動き出す

クリーンアップは1日1回でいいので、1度実行されたらそれていたら、その日はそれ以上実行しないようにする処理も必要になる

2011/06/23

[JavaScript] iPhone、アンドロイドでのクリックイベント

スマートフォンでonclickなどのクリックイベントを設定しようとすると、どうにも動きがもっさりする。

理由はダブルクリックかどうかの判定をするために、コンマ数秒待つからみたい。
これだと気持ちいい動きが実現できないので、スマートフォンではonclickではなく、ontouchendを使ったほうがいい。
そうすれば指を離した時点で、ダブルクリックかどうかの判定を待つことなくイベントが発生する

気になる点と言えば、スクロールして指を離した時にもこのイベントが発生すること。
どこかリンクなどの上にタッチしてスクロール→指を離した時点でイベント発生!
これはユーザーが意図した動きではなさそうなので、スクロールした場合はイベントは発生しないようにしといたほうがいい

タッチ系のイベントは3つ
ontouchstart
ontouchmove
ontouchend
//スクロールしたかどうかの判定フラグ
var touchMoveFlag = false;

element.ontouchmove = function(){
 //touchMoveイベントが発生したらフラグをたてる
  touchMoveFlag =true;
}

//指を離した時の処理
element.ontouchend = function(){

  //スクロールしてから指を離した場合は何もしない
  if(touchMoveFlag){
    touchMoveFlag = false;
    return false;
  }

  //スクロールしなかった(通常のクリックと同じ扱い)
//ここに処理を書く
  alert("クリックしたと判定しますよ" );

  //指を離したあとなのでフラグはひっこめる
  touchMoveFlag = false;
}




ontouchendだとダブルクリック判定ができないので、そこは注意。

参考:
[javascript]iPhone clickイベント

2011/06/22

[JavaScript] cssセレクタでDOMを取得できるquerySelector, querySelectorAll

jQueryみたいなライブラリでは当たり前の機能になってますが、cssセレクタみたいな指定方法でDOMを取得できるのはとても楽。

実はjQueryライブラリを使わなくても同じ方法でDOM取得できるらしい

document.querySelector("#id div");
document.querySelectorAll(".class");



スマートフォンサイトつくるのに、jQuery使わずにやってみる予定なので、コレは便利
getElementsByTagNameとか親要素の兄弟要素のliなんて指定せずに済むのはありがたい

■スピード比較してみたところ…
firefox5.0で試したところ、getElementsByTagNameの方が15倍以上速かった。
36個のliを取得する処理を10000回繰り返した結果
document.querySelectorAll("li") // 170ms
document.getElementsByTagName("li") //10ms



IDの場合(こっちも1000回)
document.querySelector("#id"); //47ms
document.getElementById("id"); //13ms


cssセレクタ式で指定できるのが便利な時だけ使うほうがいいかも


参考
IE8 で実装された Selectors API とは何か?IT戦記

このブログ書き終わったところでこんなページを見つけてしまった
getElementsByTagName()がquerySelectorAll()より高速な理由

2011/06/21

[JavaScript] オブジェクトにプライベート変数(らしきもの)を作る

JavaScriptのオブジェクト内に外部から編集不可なプライベート変数とそのゲッターの作り方

var OBJ = (function(){


    //varで宣言しているので、このfunction内のローカルな変数になる
    var name = 'Steve';

    return {
        getName: function(){
            return name;
        },
        sayHello: function(){
            return 'Hello,' + name;
        }
    }

}());
OBJ.getName(); //Steve
OBJ.sayHello(); //Hello,Steve
OBJ.name; //undefined


var name は functionに囲われているので、その外には存在しないローカルな変数になる。
なので外からはアクセスできない

ローカル変数を変更するメソッドも作れる


return {
    getName: function(){
        return name;
    },
    sayHello: function(){
        return 'Hello,' + name;
    },
    setName: function(val){
        name = val;
    }
}

OBJ.setName('unko');
OBJ.getName(); //unko;








2011/06/16

[WordPress]抜粋があるかどうか判定する

WordPressで抜粋を記入している場合とそうでない場合で表示方法を変更したい場合は
has_excerpt()
で判定できる。

postIDを指定したい場合は引数にidを渡せばOK
has_excerpt($id)

[Prototype.js]$$()で取得したDOMは他要素への参照ができない

タイトルそのままなんだけどprototype.jsで$$()で要素を取得した場合、他の要素にアクセスできなかった。

$("id").parentNode → お父さん要素取得
$$("#id").parentNode → undefined

$("id").getElementsByTagName("span") → 子供span取得
$$("#id").getElementsByTagName("span") → undefined

jQueryやmootoolsに慣れた身にはショッキングだった

2011/06/15

iPhoneヒューマンインターフェイスガイドラインのまとめ

スマートフォン向けサイトを作ることになったので、「アップル ヒューマンインタフェースガイドライン」を一度しっかり読んでみた。
これはメモっといた方がいいなって点のメモ

※重いので注意
iPhoneヒューマンインターフェイスガイドライン[pdf]

 ■プラットフォームの特徴
画面サイズに違いがある
iPhone4 640*960 960*640
iPad 768*1024 1024*768
その他iPhon, iPod 320*480 480*320

・ボタンなんかのUI要素の最小サイズは44*44ポイント
ポイント≠ピクセル
Retinaディスプレイでは1ポイントが2ピクセル
通常のディスプレイは1ポイント1ピクセル
つまりRetinaディスプレイでは最小サイズは88*88ピクセル

vewportで表示比率を指定する場合は横幅320で考えて良さそう





読んだらその都度追加していきやす

JavaScriptでURLのアンカー(ハッシュ)を取得する

AJAX、AJAXなんつってもう何年も経つ。
どんどん進化していっとるが、最近、ページ全体の読み込みを全くせずに表示しているコンテンツが変わるサイトが増えた

こんなん↓
http://www.kokokaka.com/#id=15awesomeyoutubetricks

こういうサイトではURLにハッシュ(#honyararaみたいなやつ)を付けて表示する中身を変更しているものが多い
#以降の文字列をJavaScriptで判断して、処理を変えてるんだと思う。
で、そのアンカーというかハッシュという部分を取得する方法
location.hash
↑で上記のサイトのURLの場合だと「#id=15awesomeyoutubetricks」が取得できる

さらに「=」の部分で分割したい場合は
location.hash.split("=");
↑で["#id", "15awesomeyoutubetricks"]という配列が返ってくる

2011/06/10

[Linux]シェルコマンドで文字列表示と引数の受け渡しとループ処理

まず1行目にはこれ。
#!/bin/sh
意味は#!で書かれたプログラムで実行しますってこと

■文字を表示する
echo "text"

■引数の受け渡し
・渡し方
command hikisuu
↑これでOK

・受け取り方
echo $1
これで1番目の引数を受け取ることができる。

引数が複数ある時は$2, $3と増やしていけばOK
$*で全部の引数を受け取る


■コマンド内で変数を使う
command="command $1";
↑コレで変数commandの中に受け取った引数を入れた文字列を格納した。
※注意 =の前後にスペースを入れてはいけないよ
echo $command
↑作った変数を使うときは$を付ける。

■繰り返し処理する(ループ処理)
・while
count=1
while [ $count -le 繰り返したい回数 ];
do
//ここに処理
count=`expr $count + 1`
done


参考:bashで始めるシェルスクリプト基礎の基礎

2011/06/09

[WordPress]カテゴリー取得方法

WordPressでカテゴリーを取得する方法のまとめ

■現在表示中の記事・アーカイブのカテゴリーを取得したい
・get_the_category()
記事のカテゴリー名、ID、 スラッグなどをphpの配列で返してくれる
現在表示中の記事やアーカイブのカテゴリーを返してくれるのだけど、$postが変更されていると、予期せぬ値が返ってくることも。

■全部のカテゴリーIDを取得したい
・get all category ids()
カテゴリーのIDが配列で返ってくる

■カテゴリーIDで取得したい
・get category(カテゴリーID)
カテゴリーIDを指定して、配列を取得する
カテゴリーのオブジェクトを引数に渡すこともできる

■スラッグで調べる
get_category_by_slug('name')
カテゴリーのスラッグで調べてphpの配列で返してくれる

■親カテゴリーを取得する
・get category parents(カテゴリーID)
親カテゴリーを返す
IDを指定すると、指定されたカテゴリーの親カテゴリーを返す。
何も指定しない場合は現在表示中のカテゴリー・記事のカテゴリーを返す

IE7 cssできないことまとめ

最近サイトを制作する際に、IE6は対応しないでいいってことがほとんどになった。
何年も苦しめられたことを思い返すと、もし会うことがあったら2度とインターネットなんかする気になるくらいボコボコにぶん殴ってやりたいってくらい積もり積もった恨みがあるけど、もう相手にしないでいいてのはとてもありがたい。

で、HTML5だCSS3だの新機能を使ってリッチな感じにしたろうやないかと意気込んで制作すると、IE7で出来ないことが多すぎて色々つまずく。
ので、しばらくはIE7は対象ブラウザとして居座るだろうから、IE7で出来ないことをまとめとこう。

■box-shadow
無理。
↓ここみたいなことしたかったけどだめ。
box-shadowを使って洗練されたエフェクトを加える二つのテクニック
立体感のある水平線をCSSだけで実現する方法

他のcssはその都度追加していきます


■ホントはIE7も社会的に抹殺してやりたいが…

「プログレッシブエンハンスメント」という考え方もあるみたいですが、IE7はまだまだ無視できないもんな~
プログレッシブエンハンスメント(Progressive Enhancement)という考えかた

※20代~50代くらいの男性ユーザーをメインターゲットにしたサイトではIE7は全体の8.5%だった。(2011/06/09現在)
思ったより少ないけど、無視できるほどではないな。
女性ユーザーは男よりもIE7の割合がまだ高そうだし。
ちなみに同じサイトでIE8は45%だった。

[Linux]rmコマンドでディレクトリ内ファイルを*(アスタリスク)で指定すると隠しファイルが削除されない

ディレクトリの中身だけ削除する処理があって、中身がファイルだろうとディレクトリだろうと消してしまうんだけど、元のディレクトリは残しとかないといけないってことがあって

rm -rf /home/path/dir/*

ってコマンドで、簡単にディレクトリの中身消せるなと思ってたんだけど、コマンド実行後に実際にディレクトリの中身をみると「.htaccess」が残ってた。

どうやら*で指定すると、隠しファイルは削除出来ないみたい。

とりあえずは上のコマンドとは別にもう一回

rm -rf /home/path/dir/.htaccess

ってコマンドを実行することにした。
.htaccess以外の隠しファイルは削除していいのかどうかはっきりしてなかったんで、とりあえず.htaccessだけを指定したけど、正規表現でうまく指定できれば一回で終わりそう。

2011/06/07

携帯電話、各キャリアの送信容量制限

ブログのシステムを作る機会があって、携帯電話からメールを送って更新する機能を付けていたんですが、最近になって、うまく投稿できないという問い合わせが出てくるようになりました。

どうやら添付している画像が大きすぎて、サーバーの受信するメール容量制限をオーバーしてしまっていたっぽい。容量オーバーの時はログをとっていなかったらしく、こっちのサーバーまで届いていたのかどうか確認できなかった…。
 今までは起きてなかったことなので、おそらく スマートフォンが普及してきたからかなと思われる。


とりあえず上限を2MBにアップして対応。
キャリアや機種によっては2MBを超えるので、受信してから容量を調べて、オーバーしていた時は通知メールを返すなんてのがよさそう。

いい機会なので、携帯キャリアのメール送信上限を調べてみた。

■Docomo

大容量メール対応機種は2MB
http://www.nttdocomo.co.jp/service/communication/imode_mail/function/
spモードだと合計10MB
http://www.nttdocomo.co.jp/service/provider/spmode/function/mail/function/index.html

※添付された画像を縮小したりする処理があるので、10MBの画像がくるとなるとキツイ…。


■au

1ファイルあたり500KB
一部の機種はjpgのみ2MBまで
添付ファイルは5個まで(デコメは20個まで)
合計2MBまで
http://cs119.kddi.com/faq/1032/app/servlet/qadoc?QID=000103



■SoftBank

□通常メール
大容量ファイル機能、最大2MB
http://mb.softbank.jp/mb/service/3G/mail/

□iPhone
・i.softbank.jp
1MB
http://mb.softbank.jp/mb/iphone/service/mail/email_i.html

2011/05/27

prototype.jsで要素を追加する

prototype.jsでは
$(要素).insert(追加要素);
で新しく要素を追加できる。


■新しい要素をどこに追加するかを指定する
$(elem).insert("top", 要素);
topと指定すると子要素の最初に追加される。

他には
$(elem).insert("bottom", 要素);
で最後に追加。位置をしていしない場合も最後の子要素として追加される。

子要素としてではなく、兄弟要素として指定の要素の前後に追加することもできる。
$(elem).insert("before", 要素);
$(elem).insert("after", 要素);

参考:
いまからはじめるPrototype.js (5) HTML要素とフォームに関するメソッド マイコミジャーナル


Action Script3でムービークリップのオンマウス時のカーソルをリンクと同じポインターにする

movieclip.buttonMode = true;

これで、ムービークリップがボタンモードになる。
オンマウス時にマウスカーソルが通常のリンクと同じポインターになる。

もし、クリックして別のページに移動する機能をつけたいって時は

//クリックイベントを登録
movieclip.addEventListener(MouseEvent.CLICK, onClick);

function onClick (event:MouseEvent):void {

var url:String = "http://www.example.com/";
var request:URLRequest = new URLRequest(url);

navigateToURL(request, "_self");
}

2011/05/24

firebugでJavaScriptの処理時間を計測する

firebugで、処理の時間を計るなら
console.time(name)
//処理
console.timeEnd(name)
と書くと処理の部分にかかった時間を測定出来ます。

計測できる一番小さい値が1msなので、1回の処理だとあまり違いがわからないこともあると思うので、そういう場合は1000回とか同じ処理を繰り返してみると、違いが分かりやすいと思います。


var name = 'test';
console.time(name)

//テストする処理
for(var i = 0; i < 1000; i++){

var div = $("");

}

console.timeEnd(name)

2011/05/23

jQuery親要素、子要素、兄弟要素取得のまとめ

※各メソッドにかいてある[条件]ってのは、タグ名やid、クラス名を指定するってことです。
条件を入れると、条件にあったものだけが取得されるようになります。
例:$(elem).parent("div.class-name, #id");
通常のJavaScriptでの要素取得方法は→[JavaScript] 親要素・子要素・兄弟要素の取得方法


■親要素の取得

parent([条件])
親要素の取得。
すぐ上の親要素のみ。さらに上の先祖要素にはさかのぼらない。
$(elem).parent("div");
親要素がdivだったら親要素が取得できる。divじゃなければ空。

parents([条件])
parent()と違い親より上の先祖要素までさかのぼる。
$(elem).parents(".class-name");
class-nameというクラス名がついた先祖要素のみ取得

closest([条件])
最も近い先祖要素を取得
$(elem).closest("div");
で一番近いdivを取得。間にpタグなんかあっても無視。


■子要素の取得

children([条件])
全ての子要素を取得。
対象は子要素のみ。孫要素以下は対象外。
$(elem).children("span");
子要素のspanだけ取得

contents()
テキストノードを含めた子要素を全部取得する。
条件をつけることはできない。

find([expr])
子要素だけじゃなく、全子孫要素が対象。
条件を入れた場合は、条件にあった子孫要素だけ取得
$(elem).find("div");
子孫要素のdivだけ取得。


■兄弟要素の取得

next([条件]);
すぐ次にある要素を取得する。
取得する要素は、すぐ次にある1つだけ。
当然、自分の前にあるものは取得しない

nextAll([条件])
次以降にある全要素を取得する

prev([条件])
next()の逆。
自分のすぐ前にある要素を1つだけ取得。

prevAll([条件])
前にある要素を全部取得。
もちろん条件も付けられる


MySQL レコードを更新する

レコードの値を更新するにはUPDATE

UPDATE テーブル名 SET カラム名=値 [WHERE 条件]

条件を入れ忘れるとそのテーブルの全レコードが更新されてしまうので要注意。

2011/05/19

JavaScript高速化 undefined型判定編

 JavaScript高速化 関数呼び出し地獄編に続いて、今回は型判定編。
今回もWeb+DB Press Vol.58の「JavaScriptの玉手箱」を参考にしてます。

■型判定高速化

★できるだけ===(トリプルイコール)を使う
==(ダブルイコール)だと型が一致しない場合に型変換して比較するので、遅くなる。

・==の場合、null, undefinedを判別する場合は便利
==だとnull, undefinedを同時に判別してくれる
valがundefinedの場合
val == null
で比較してもtrueが返ってくる




□undefinedの判別
変数がundefinedかどうかを判定する方法は4つ
1.ダミー変数と比較
2.typeofで文字列と比較
3.window.undefinedと比較
4.void演算子でundefinedを生成して比較

この中で処理が早くて著者もオススメしてるのが4番のvoid演算子でundefinedを生成して比較

if(val === void 0){}

※void演算子はその場でundefinedを作ってくれる

1番はChrome以外でほぼ最速。でもChromeだと遅い(といってもIE8の半分以下の時間しかかからないみたい)。
2番はChrome以外で遅い。特にOpera、FireFoxで遅い
3番はFireFox以外で遅め。


mootoolsでアニメーション開始時、終了時に処理をする

mootoolsのアニメーション、tweenやmorphのアニメーションの始まる直前やアニメーションが終わった直後になにか処理を動かしたりするにはonStart, onCompleteを使う。

var tw = new Fx.tween(id, {
  duration: 100,
  onStart: function(){
    //アニメーション開始直前の処理
  },
  onComplete: function(){
    //アニメーション終了直後時の処理
  }
});

参考
[mootools]スクロールに追随させる - mooFollow.js

2011/05/11

auでフォームを送信すると404になる

自分の場合、formの送信先を表示中のページにすることが多い。
同じページで送信されたデータを受け取って、そのデータによってリダイレクト先を変えたりするため。
formの送信先を設定するのにformタグのaction属性を「action=''」と空にしておくと、自ページに送信することができるんだけど、auの機種によっては送信ボタンを押すと404になってしまいで送信できなくなる。
なので携帯からアクセスされる可能性がある場合はformのactionは空にしないようにしてる。

スマートフォンは大丈夫だと思うけど…auのスマートフォンを持っていないため確認できてない。

2011/05/10

WordPressにflckrの画像をランダムに表示する。

WordPress内にflckrの画像を表示するには
俺はflickrRSSというプラグインを使ってます。
管理画面で「プラグイン」→「新規追加」→「flickrRSS」で検索すると出てきます。

これがRSSというだけあって、新しい順で画像を表示するんだけど、デフォルトではコレを変更できない。
なので、プラグインのファイルをちょこっと改造します。
flickrRSSのバージョンは5.1です。

■改造
・プラグインフォルダの中にある「flickrrss.php」ってファイルを開く。

・141行目に
$items = array_slice($rss->items, 0, $settings['num_items']);
ってコードがあります。
見つからない場合は、「array_slice」でファイル内を検索すると出てくると思う。
バージョン5.1ではarray_sliceは1箇所でしか使われてないけど、他のバージョンではどうなのかわからないので、注意して試してください。

このコードの意味は「$rss->items」っていう全画像データの0番目から$settings['num_items']番目までを抜き出すってことです。
$settings['num_items']ってのは管理画面から設定した表示枚数ね。

「$rss->items」ってのが画像のデータなんだけど、デフォルトではこれが新しい順に並んでる。
なので、これをランダムにしてしまいましょう。

shuffle($rss->items);

これだけ。
これを上に書いた141行目のコードの前に入れるだけ。

これでランダムになります。

プラグインの使い方なんかはこんなページを参考にどうぞ
WordPressにFlickrを読み込めるプラグイン「FlickrRSS」

2011/05/02

iPhone対応用にサイトの幅を設定する

スマートフォン用に幅を設定するには<head>内にmetaタグを追加する

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

contentの中身は

■width=***
ここで表示する横幅を指定する。
ここには数字を入れてpx幅を指定することもできるらしい。
機種によって幅が違ったり、端末を横にすると幅が変わったりしてもそれに合わせて表示したい場合は"device-width"と入れると、各端末の幅に合わせてくれる

■initial-scale=*
初期表示の倍率。1で通常表示。2にすると2倍。

■maximum-scale=*
拡大可能な倍率。画面を拡大する場合の最大の拡大率を設定する。

他にも
■user-scalable
ユーザーが拡大・縮小できるかどうか。yes/noで設定する。

■height
高さ設定。device-heightで端末の高さに合わせられる

■minimum-scale
縮小した場合の最小の倍率の設定

ちなみにWordPressでiPhoneで見た場合は、iPhone用のテンプレートに切り替えて表示したいって場合は「iphone theme switcher」ってプラグインがある。
詳しく説明してくれている方がおります。
iPhoneからアクセスした時のテーマを指定できるWordPressプラグイン「iPhone theme switcher」

iPhoneに限らず、いろんなブラウザや端末しだいで、それぞれテンプレを変更するためのプラグインもあったと思うけど、思い出せなかった。思い出せたら追記しよう。


参考サイト
iPhone 3G用のWebページを作る[AllAbout]
作って学ぶスマートフォン対応サイトの基本

2011/04/30

WordPress 一覧表示カスタム

■月別表示
基本
wp_get_archives();
2011年4月

後ろに件数出したい
wp_get_archives('show_post_count=true');
2011年4月(1)

詳細→テンプレートタグ/wp get archives

2011/04/28

Cookie と Session ID

・そもそもCookieとはなんぞや
俺の勘に狂いがなければ恐らくカントリーマアムの仲間かなにかだろうと思われる。
仮説の検証としてカントリーマアムを自宅のPCのCDトレイに入れてみたところ、トレイがうまく閉まらない。
どうやらカントリーマアムとCookieとやらは別物らしい。

サーバサイドからクライアントに対して書き込める小さなテキストのこと

サードからブライアントに向けて投げ込んだらテキサスヒットになった?
意味がわからん

どうやらサーバー側からブラウザに情報を書きこめるらしい。
そのブラウザでページを見たときにそのCookie情報がサーバーに渡される
Cookieはブラウザ側に書きこむので、ページを閉じた後もブラウザに残る。
ブラウザ側にあるのでユーザーが中身を変更できる、送信途中に誰かに見られる可能性があるので、セキュリティに関わる情報は載せちゃダメ。

・セッションとはなんぞや
俺の勘に狂いがなければ恐らくセックスの際に使いやすいクッションことだと思われる。
仮説の検証をしたかったが相手が見つからないので断念した。

サーバー側に情報を保存しておく
ブラウザにセッションIDというキー情報だけを渡す。これでユーザーを識別できる。これもヘッダ情報として送信されてくる。
サーバー側に残ってるデータとセッションIDは割印みたいになってるっぽい。形が合致すればデータを使える
セッション情報の保存期間は一般的に数分~数時間


参考ページ
http://thinkit.co.jp/free/article/0604/7/8/
http://www.phppro.jp/school/phpschool/vol8/1

JavaScript高速化 関数呼び出し地獄編

Web+DB Press Vol.58の「JavaScriptの玉手箱」でJavaScriptの高速化に関する記事があった。
※「JavaScript高速化 undefined型判定編」ってのも書きました

■関数
・関数呼び出しのコスト
JavaScriptは関数呼び出しのコストが高い
関数を小分けにし過ぎると呼び出す回数が増えて遅くなるので、ある程度はインラインで書いて、関数呼び出しの回数を減らした方が速くなる

・関数の呼び出し
同じスコープ内にある関数かグローバルな関数は速い
でもグローバルな関数をwindow["hahihuheho"]という書き方で呼ぶとえらく遅くなるらしい。

呼び出し早い順ランキング
1.グローバル関数をwindowを省略して呼ぶ
2.上位スコープの関数を呼び出す
3.ローカル関数を呼び出す
4.グローバル関数をwindow["****"]で呼ぶ

自分的に意外だったのはローカル関数呼ぶより上位の関数呼んだほうが速いってこと。
各ブラウザでのテスト結果も出てたんだけどChrome以外は大きな差があった。

※ローカル関数呼び出し
function func1(){
    fucntion localFunc(){
         return true;
    }

    localFunc();
}
↑よりも↓の方が速い

※上位スコープの関数呼び出し
function func1(){
     scopeFunc();
}
※↓上位スコープにある関数
function scopeFunc(){
    return true;
}

兄弟に相談するよりも、親に聞いた方がいいってイメージで覚えとこう

他にも型判別の高速化に関しても書いてあったので、また今度。



2011/04/27

SymfonyでAjaxからのアクセスのみ許可する

$this->getRequest()->isXmlHttpRequest()
Ajaxでのアクセスだと、返り値がtrueになる。

if($this->getRequest()->isXmlHttpRequest()){
  //Ajaxでのアクセスの場合のみ行う処理
}
こういう風に書けば、Ajax以外のアクセスは何もしないとか404にしてページを表示しないとかできる。


参考
Symfonyドキュメント