煽りタイトルを付けようと思ったら元からそんなタイトルだった。
ということで以下はjQuery Tips Everyone Should Knowの日本語訳です。
イタリックは元記事にはない訳者(私だ)による補足です。
jQuery Tips Everyone Should Know
これは、とても役に立つjQueryのTips集だぞ。
Checking If jQuery Loaded
jQueryで何かするには、最初にjQueryがロードされてるか確認する必要があるぞ。
if (typeof jQuery == 'undefined') {
console.log('jQueryがない!');
} else {
console.log('jQueryがある');
}
残念ながら君はのけものだ。
Use .on() Binding Instead of .click()
.on()
は複数のイベントを追加できるなど、明らかに.click()
より優位なのでonを使うべきだ。
.on('click tap hover')
このバインドは後から動的に追加した要素にも自動的に適用されるから、一回書けばいちいち手動でバインドを追加する必要は無いぞ。
あとnamespaceも書ける。
.on('click.menuOpening')
namespaceを使うと特定のイベントだけ解除するとかできて便利だぞ。
Back to Top Button
animate
とscrollTop
を使うだけでTOPへ戻るボタンが簡単に作れるぞ。
プラグインも何もいらない。
// 戻るボタン
$('.container').on('click', '.back-to-top', function (e) {
e.preventDefault();
$('html, body').animate({scrollTop: 0}, 800);
});
<!-- HTMLタグ -->
<div class="container">
<a href="#" class="back-to-top">TOPへ戻る</a>
</div>
scrollTopの値を変更すると、スクロールバーの進む先が変わるぞ。
上のソースがやっているのは、800ミリ秒かけて最上部にスクロールするアニメーションだ。
注意:scrollTopにはバグがあるから見とけよ。
Preload Images
hoverで表示される画像など、最初からは表示されない画像をたくさん使っている場合、それらはプリロードしておくといいぞ。
$.preloadImages = function () {
for (var i = 0; i < arguments.length; i++) {
$('<img>').attr('src', arguments[i]);
}
};
$.preloadImages('img/hover-on.png', 'img/hover-off.png');
せっかくjQuery使ってるんだから$.each
とか使った方がいいのではなかろうか。
Checking If Images Are Loaded
画像の読み込みが完全に終わってからスクリプトを進めたい場合もあるだろう。
$('img').on('load', function () {
console.log('全画像読み込み終わった');
});
img
タグを他のidやclassに置き換えれば、特定の画像がロードされたことを検出できるぞ。
Fix Broken Images Automatically
リンク先の画像が存在しなくて読み込めなかった場合、そのリンクを一個一個調べて修正するのは大変だ。
ちょっと以下のコードを書いておくと代わりに壊れ画像を表示してくれるぞ。
// 画像の読み込みに失敗したらかわりにimg/broken.pngを表示する
$('img').on('error', function () {
if(!$(this).hasClass('broken-image')) {
$(this).prop('src', 'img/broken.png').addClass('broken-image');
}
});
あるいは以下のように書けば読み込めなかった画像を隠してくれるぞ。
$('img').on('error', function () {
$(this).hide();
});
いや、ちゃんとlintなりソフトなりで調べて修正しろよと。
Post a Form with AJAX
jQueryはajaxメソッドでテキスト、HTML、XML、JSONなんかを簡単に送信できるぞ。
JavaScriptでフォームを送信する場合、val()
メソッドでユーザ入力値を取得できるぞ。
// sign_up.phpに3値をPOSTする
$.post('sign_up.php', {
user_name: $('input[name=user_name]').val(),
email: $('input[name=email]').val(),
password: $('input[name=password]').val(),
});
ただ毎回個別にval()
を呼び出すのは高コストだ。
かわりにフォームの中身をまとめて文字列にするserialize()があるのでそちらを使った方がベターだ。
$.post('sign_up', $('#sign-up-form').serialize());
Toggle Classes on Hover
クリックできる要素をわかりやすくするため、hoverしてるときだけ演出を変えたいときがあるだろう。
以下のように書けば、hover時にクラスを追加して、離れたときにクラスを削除できるぞ。
// btnクラスにhoverしているときだけhoverクラスを追加
$('.btn').on('hover', function () {
$(this).addClass('hover');
}, function () {
$(this).removeClass('hover');
});
あとは必要なcssを追加するだけだ。
そしてtoggleClass
を使えばもっと簡単に書けるぞ。
$('.btn').on('hover', function () {
$(this).toggleClass('hover');
});
注意:上記の場合は単に:hover
疑似クラス使えばいいだけだしそちらの方が高速だけど、このような書き方があるということ自体は知っておく価値はあるぞ。
Disabling Input Fields
ユーザが特定の動作を行う(たとえば「利用規約に同意する」をチェックする)まで、フォームの送信ボタンや一部のテキスト入力欄などを無効にしておきたい場合があるだろう。
属性disabled
を入れるだけで簡単に実装できるぞ。
$('input[type="submit"]').prop('disabled', true);
同意したら今度はdisabled
をfalseにするだけでボタンが有効になる。
$('input[type="submit"]').prop('disabled', false);
Stop the Loading of Links
aタグを押してもリンク先に飛ばさないようにしたり、ページのリロードをさせたくない場合があるだろう。
あるいは他のスクリプトを呼び出したりしたいかもしれない。
そういうときにはデフォルトの動作を止めることができる。
$('a.no-link').on('click', function (e) {
e.preventDefault();
});
preventDefaultはjQueryの機能ではない。
Cache jQuery Selectors
同じセレクタを何度も使いたいときに$('.element')
を毎回書いていると、そのたびにDOM全体を検索しに行ってしまう。
かわりにセレクタは一回だけ実行し、結果を変数に入れておくとよい。
var blocks = $('#blocks').find('li');
最初に一度実行しておくだけで、以後は毎回DOMを見に行ったりせずにblocks
を使い回すことができる。
$('#hideBlocks').on('click', function () {
blocks.fadeOut();
});
$('#showBlocks').on('click', function () {
blocks.fadeIn();
});
セレクタをキャッシュしておくことで、簡単にパフォーマンスを上げることができるぞ。
当然だが、セレクタの実行後にDOMを変更してもキャッシュの内容は変わらないので注意すること。
Toggle Fade/Slide
フェードやスライドはアニメーションで頻繁に使う演出だ。
ユーザが何かをクリックしたら要素を表示したいという場合はfadeIn
やslideDown
を使うと簡単だ。
しかしクリックしたら隠したり表示したりを繰り返したい場合、jQueryには専用のメソッドがある。
// フェード繰り返し
$('.btn').on('click', function () {
$('.element').fadeToggle('slow');
});
// スライド繰り返し
$('.btn').on('click', function () {
$('.element').slideToggle('slow');
});
Simple Accordion
超簡単なアコーディオンメニューの例だ。
// contentは最初は全部隠す
$('#accordion').find('.content').hide();
// accordion-headerボタンを押したらcontentを表示する
$('#accordion').find('.accordion-header').on('click', function () {
var next = $(this).next();
next.slideToggle('fast');
$('.content').not(next).slideUp('fast');
return false;
});
これ以外に必要なものは、メニューのHTMLだけだ。
Make Two Divs the Same Height
複数のdivが存在し、中身がばらばらである場合に、全ての要素を同じ高さに合わせたい。
$('.div').css('min-height', $('.main-div').height());
この例はmin-height
を設定している。
.div
要素は.main-div
要素より大きくなることはあるが小さくなることはない。
もっとよりよい方法は、最も高さのある要素に全ての要素の高さを合わせることだ。
var $columns = $('.column');
var height = 0;
$columns.each(function () {
if ($(this).height() > height) {
height = $(this).height();
}
});
$columns.height(height);
全ての列の高さを揃えたい場合は以下のようにする。
var $rows = $('.same-height-columns');
$rows.each(function () {
$(this).find('.column').height($(this).height());
});
注意:これはCSSで調整した方が手っ取り早いが、JavaScriptで行わないといけないこともあるから知っておく価値はある。
Open External Links in New Tab/Window
同じドメイン内のリンクにはそのまま進み、外部リンクは別ウィンドウで表示させたい場合は以下のように書けばよい。
$('a[href^="http"]').attr('target', '_blank');
$('a[href^="//"]').attr('target', '_blank');
$('a[href^="' + window.location.origin + '"]').attr('target', '_self');
注意:window.location.origin
はIE10では動かない。対応したい場合はこのfixを入れるとよい。
Find Element By Text
contains()セレクタは、引数の文字列が含まれている要素を見つけてくれる。
以下は引数の文字列が入ってない要素を非表示にする例だ。
var search = $('#search').val();
$('div:not(:contains("' + search + '"))').hide();
Trigger on Visibility Change
別のタブを開いたとかウィンドウを最小化したとかで画面が表示されなくなったとき、また再び画面が表示されたときをvisibilitychangeでトリガーできるぞ。
$(document).on('visibilitychange', function (e) {
if (e.target.visibilityState === 'visible') {
console.log('タブが画面に表示された');
} else if (e.target.visibilityState === 'hidden') {
console.log('タブが隠れた');
}
});
Ajax Call Error Handling
Ajax呼び出しが404や500を返してきたときはエラーハンドラが実行される。
その際エラーハンドラが定義されてなければもうjQueryのコードは動かなくなってしまう。
以下のコードでグローバルなAjaxエラーハンドラが定義できるぞ。
$(document).on('ajaxError', function (e, xhr, settings, error) {
console.log(error);
});
きちんとDeferredを使えと。
Chain Plugin Calls
メソッドチェーンを使えば、jQueryが何度も同じオブジェクトを作成してしまう無駄を省けるぞ。
以下のようなコードがあったとしよう。
$('#elem').show();
$('#elem').html('bla');
$('#elem').otherStuff();
メソッドチェーンでコストは大幅に改善する。
$('#elem')
.show()
.html('bla')
.otherStuff();
もしくは要素を変数にキャッシュしてもいい。
var $elem = $('#elem');
$elem.hide();
$elem.html('bla');
$elem.otherStuff();
チェーンとキャッシュをうまく使いこなせば、より簡潔で高速なコードを書けるようになるだろう。
Sort List Items Alphabetically
リストに大量のアイテムが並んでいるとしよう。
そのリストはCMSによって作成されたのだが、ID順に並んでいるのでアルファベット順にソートしなければならない。
var ul = $('#list'),
lis = $('li', ul).get();
lis.sort(function (a, b) {
return ($(a).text().toUpperCase() < $(b).text().toUpperCase()) ? -1 : 1;
});
ul.append(lis);
できたー!全部できたー!
訳者による感想
Everyone Should Know?
正直Tipsとしてはかなり微妙。
なんかもっとこう驚きのアイデアなんかが書かれてるのかと思っていたら、特になんてことない普通の内容しかなかった。