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