Javascript

JavascriptのsetTimeout()は引数の渡し方に注意。

嵌ったのでメモ。

例えば下記のような関数が定義されていたとする。

var noname = function(arg1, arg2, arg3){
	console.log(arg1);
	console.log(arg2);
	console.log(arg3);
}

まずsetTimeoutで単純に関数を呼びたいだけの場合。
第1引数に関数名を指定する際、クオーテーションで括る方法と括らない方法があるので注意。

// 括る場合
setTimeout('noname()', 1000);
// 括らない場合
setTimeout(noname, 1000);

第1引数をクオーテーションで括った場合、関数名の後に括弧「()」が無いと正常に動作しない。
逆に括らなかった場合は括弧をつけてしまうと意図しない動作になる。

下記に示す記述方法はいずれも正常に動作しない例。

// 第2引数のms指定は無視され、即座に関数が呼び出される。
setTimeout(noname(), 1000);
// もはや動作しないパターン。
setTimeout('noname', 1000);

次にnoname()関数に変数を渡したい場合の記述方法。
この際もクオーテーションで括る場合と括らない場合で変数の渡し方に違いがあるので注意。

// 括る場合
setTimeout('noname("first", "second", "third")', 1000);
// 括らない場合
setTimeout(noname, 1000, 'first', 'second', 'third');
↓
[console]
first
second
third 

そして下記は例の如く正常に動作しない。

// 指定の間隔後に関数は呼び出されるが、変数は渡されない。
setTimeout('noname()', 1000, 'first', 'second', 'third');
// 変数は渡され実行もされるが、第2引数が無視されるので即座に呼び出されてしまう。
setTimeout(noname('first', 'second', 'third'), 1000);

見るページごとに書いてあることが違う気がするけど、全てちゃんと実験したので上記の情報は間違いないはず。
※問題児(IE)でもデバッグ済み。

Javascriptではオブジェクトの最終引数後のカンマに注意する。

PHPとかだとよくやってしまいそうなミス。

var obj = {"my":"banana","favorite":"apple","fruit":"orange",}

上記は、最終引数後のカンマを取り除き忘れた際の例。
ブラウザによってはこれが原因でエラーになり処理が中断されるので注意が必要。

例えばjQueryでAjax処理を記述する際。

$.ajax({
	url : url,
	type : 'POST',
	data : data,
})

$.ajax()関数に渡しているオブジェクトに注目。
この場合も同様、最終引数後のカンマが原因となり通信が中断されてしまう可能性がある。
Chromeなどのモダンブラウザは適切に解釈してくれるが、IEは当然のごとくコケるのでくれぐれも注意されたし。

jQueryにてAjaxのコールバックにオブジェクト内の関数を割り当てる。

何かしらのAjaxの処理が完了した際、その場で無名関数をゴリゴリ記述しても動作に問題はないが、どうしても可読性と美しさに欠ける。
そんなときにお勧めなのがこの書き方である。

まずはオブジェクトを宣言し、内部にコールバックで実行したい関数を定義する。

var myFuncs = {};
myFuncs.callback = function(data){
    // 処理
}

今度は同オブジェクト内にAjaxの処理を追加。
そしてコールバック関数のdone()内を以下のように記述する。

myFuncs.ajax = function(){
	$.ajax({
		url: url,
		type: 'POST',
		data: data
	}).done((function(obj){return function(d){obj.callback(d)}})(this));
}

こうすることでオブジェクトmyFuncs内のcallback()関数をAjax完了後の処理として割り当ててることが出来る。
この挙動を説明するためには、Javascriptにおけるthisが何を指しているのかを理解する必要がある。
分かり易いよう、done()のみを取り出すと以下のようになる。

done(
		(function(obj){
			return function(d){
				obj.callback(d)
			}
		})(this)
	);

done()直後のfunction()はこのエントリ←で紹介した文法を用いて関数を記述したもの。
流れとしてはまず、戻り値として関数自体を返却する関数にthis(この場合オブジェクトmyFuncsを指す)を渡し変数objとして受け取る。
次に、Ajaxからの返り値を「d」として受けとり、obj内のcallback()関数にその「d」を渡す関数を記述し、その関数自体を返却(return)する。
こうすることでthisのスコープを上手いこと持ちまわしつつコールバック関数を割り当てる事が出来るので、ソースがめちゃくちゃ綺麗になる。

最初はなかなかピンと来ないが、理解してしまえばかなり便利。

レスポンシブ対応のjQueryスライダーを実装する。

その名も「bxslider」。
シンプルかつ動作もぬるぬるで、レスポンシブ対応の自分的最強プラグイン。

まずは下記の公式サイトから本体をダウンロード。
http://bxslider.com/

落としたら下記のように必要なファイルを読み込む。

<link rel="stylesheet" type="text/css" href="/css/jquery.bxslider.css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="/js/jquery.bxslider.min.js"></script>

スライダーにしたい画像を用意し、下記のようにdiv要素、もしくはul要素を使いマークアップする。

<ul class="slider">
    <li><img src="/images/img1.jpg" /></li>
    <li><img src="/images/img2.jpg" /></li>
    <li><img src="/images/img3.jpg" /></li>
</ul>

<div class="slider">
    <div><img src="/images/img1.jpg" /></div>
    <div><img src="/images/img1.jpg" /></div>
    <div><img src="/images/img1.jpg" /></div>
</div>

最後にプラグインを実行する。

$(function(){
	$('.slider').bxSlider({
		auto: true,
		speed: 1000,
		pause: 5000,
		captions: true,
	});
});

bxSlider()に渡せる引数は他にもたくさんあるので、詳細は公式サイトを参照されたし。

jQueryでHTML5のdata属性を扱う方法。

jQueryで要素を指定する際、IDやクラス以外で選択したい場合に便利。

data属性は下記の通り、ハイフン以降に任意の文字列を設定することで利用できる。

<div data-hoge="huga">piyo</div>

例えば上記の「data-hoge」属性にアクセスしたい場合は下記の記述でアクセスが可能。

$('div').data('hoge');

また以下のように、data属性に対しオブジェクトを代入することで複数の値を一度に管理できる。

<div data-info='{"my":"banana","favorite":"apple","fruit":"orange"}'>自己紹介</div>

アクセスする際は下記の通り。

$('div').data('info').my;
$('div').data('info').favorite;
$('div').data('info').fruit;

そして最後にjQuery側からdata属性を設定する方法。
これは普通にattr()関数を用いて設定すればよい。

$('div').attr({
    'data-hoge': 'huga',
    'data-info': '{"my":"banana","favorite":"apple","fruit":"orange"}'
});

Javascriptにて無名関数を即座に実行する方法。

自分用メモ。

極めて文法的なお話。

まず無名関数の基本。

var func = function(){
    // 処理
};

上記は無名関数を変数funcに代入した際の例。
実行する際は以下のように記述する。

func();

ところで、この例のように無名関数はいったん変数に詰め込んでやらないと実行できないのだろうか。
答えは否である。但し文法に注意する必要がある。

まずは普通にfuncの部分をまんま無名関数に置き換えてみる。

function(){...}();

が、これは文法的にNGとされる。ではどうすればよいか。
答えは下記の通り。

(function(){...})();

これで望みどおりの挙動を実現する事が出来る。
「function(){}」自体をもう一度括弧「()」で囲うのがポイント。
引数を渡す際も通常通り、最後の括弧に変数を入れてやればよい。

例)

(function(){...})(this);

この書き方を上手に応用すると、Ajax処理のコールバックに、オブジェクト内の関数を指定することが出来たりする(いわゆるクロージャ?)。
Javascriptは本当に奥が深い。

jQueryにて変数の型を判定する。

メモ。

$.type()関数を用いる。

var obj = {};
var res = $.type(obj);
console.log(res);
↓
// object

今回はオブジェクトの型判別に利用したが、他にもstring、number、boolean、arrayといった型の判別が可能。

jQueryのセレクター指定方法によるパフォーマンスの違いを理解する。

まずは結論。上から順に高速。

$('#hoge'); // IDセレクタ
$('div'); // タグセレクタ
$('.hoge'); // クラスセレクタ
$('#hoge').find('.hoge'); // IDセレクタ + find()、クラスセレクタ
$('.hoge', '#hoge'); // クラスセレクタとIDセレクタ
$('#hoge').find('div.hoge'); // IDセレクタ + find()、タグ、クラスセレクタ
$('#hoge .hoge'); // ID、クラスセレクタ
$('[name="hoge"]'); // 属性セレクタ
$(':hidden'); // jQuery独自セレクタ

ベンチマークスコアで表すと以下のようになる。テスト環境は次の通り。
Testing in Chrome 28.0.1500.95 32-bit on Windows Server 2008 R2 / 7 64-bit

※スコアが高いほど高速

$('#hoge'); // 1,342,595
$('div'); // 312,672
$('.hoge'); // 256,658
$('#hoge').find('.hoge'); // 175,491
$('.hoge', '#hoge'); // 158,029
$('#hoge').find('div.hoge'); // 77,628
$('#hoge .hoge'); // 26,625
$('[name="hoge"]'); // 23,506
$(':hidden'); // 1,274

こうしてみるとIDセレクタが圧倒的なパフォーマンスを誇っており、jQuery独自セレクタが圧倒的に遅い。
タグとクラスセレクタもなかなかに高速であると判明したが、結果からすると極力IDセレクタを用いた方が幸せになれそうである。
jQuery独自セレクタに関しては、わざわざ用いる場面に遭遇したことが無いのであまりピンと来ないが、実装を強いられない限り他のアプローチでどうにか解決するべきなのは間違いない。だって遅すぎるし(笑)。

更なる詳細は以下URLを参照。色々なパターンのベンチマークを見ることが出来る。
http://jsperf.com/id-vs-class-vs-tag-selectors