基礎的なものからちょっとした機能の実装方法など、jQueryに関する個人的なメモ・スニペットリストの第7弾です。
動きをすぐ確認できるデモなどは基本的に用意していないので、実際の動きを確認したい場合などは自身で簡単な環境を作成して試してもらうか「CodePen」や「JSFiddle」などを利用して確認してください。
画像のアスペクト比を割り出して、値によって処理を加える
例えば複数の画像を並べて表示したいという時に、同じサイズや同じ縦横比であればCSSなどで容易に調整可能ですが、それが横長や縦長など異なるサイズ(アスペクト比)で且つどのようなものが入ってくるのかを限定できない時などに利用できます。
jQueryを下記のように記述することでアスペクト比によってそれぞれ別の処理を実装することができ、例えばCSSのposition: absolute;
とネガティブマージンを組み合わせることで、どんなサイズや形の画像がきても表示領域で正方形のように見せるといったことも実装可能です。
$('img').each(function() {
var imgW = $(this).width(),
imgH = $(this).height(),
imgAspectRatio = imgWidth / imgHeight;
if ( imgAspectRatio >= 1 ) {
// 横長画像の場合の処理
} else {
// 縦長画像の場合の処理
}
});
ホバーした要素以外に処理
ホバー時の動きとしてよくあるのは、例えばホバーした要素の画像を置き換えるとか透過させるといったように、そのホバーした要素に対して何か処理を行うというものですが、jQueryを下記のように記述することでそのホバーした要素以外の要素に対して処理を行うことができます。
下記はサンプルとしてHTMLがul
, li
を使ったシンプルなリストの場合を想定したもので、このサンプルコードの場合はホバーしたli
要素以外のli
が.fadeTo()
によって透過されていくというものになります。
var element = $('ul li');
element.hover(function() {
element.not(this).stop().fadeTo(400, .2);
}, function() {
element.not(this).stop().fadeTo(400, 1);
});
CSSのプロパティ値を取得する
jQueryを使って特定の要素に指定されているCSSのプロパティ値を取得する方法で、下記は例として要素のwidth
の値を取得するものです。
$('element').css('width');
ただ、上記の場合は例えば要素に指定されているwidth
が300px
だった場合は「300px」とpx
付きで表示されます。
これを数値のみという形にしたい場合は下記のようにparseInt
を利用する形で記述し、こちらの方法を利用することで先ほどの例で「300px」となっていたものも「300」というように数値のみで取得できます。
parseInt($('element').css('width'), 10);
アコーディオン -特定のアコーディオンを初期表示で展開させておく-
jQueryを使ってシンプルなアコーディオンを実装する際は「9. アコーディオン – jQuery Snippets #1」で紹介した方法で実装できますが、それにもう少し手を加えたものになります。
アコーディオンは初期表示でコンテンツ部分は非表示にしておくということが多いですが、場合によって一部のアコーディオンのみ初期表示を展開させた状態にしたい時があります。
全てのアコーディオンでコンテンツ表示部分をデフォルトで展開させておくのであれば、jQueryで最初に.hide()
としている部分を削除するなどすればいいのですが、そうではなく特定のものだけとしたい場合は、下記のように.hasClass()
を利用することで実装できます。
ここではサンプルとして、HTMLでデフォルトで展開させておきたい部分のタイトルにあたる箇所にクラスを付けた場合のもので、.is-open
というclassをタイトルとなる箇所(このサンプルではdt
)に記述すれば、そのタイトルをクリックした時に表示されるコンテンツ表示部分をデフォルトで展開された状態にすることができ、下記のように記述されたHTMLをブラウザで確認するとひとつ目のアコーディオンだけがコンテンツが展開された状態になっているのを確認できます。
<dl class="accordion">
<dt class="is-open">title 1</dt>
<dd>contents 1 ...</dd>
<dt>title 2</dt>
<dd>contents 2 ...</dd>
<dt>title 3</dt>
<dd>contents 3 ...</dd>
</dl>
var $acLabel = $('.accordion dt'),
openClass = 'is-open';
$acLabel.each(function() {
if ( $(this).hasClass(openClass) ) {
$(this).next().show();
} else {
$(this).next().hide();
}
});
$acLabel.on('click', function() {
$(this).toggleClass(openClass);
$(this).next().stop().slideToggle();
});
単純なアコーディオンを実装する時は、最初にコンテンツを非表示にするために$('.accordion dd').hide();
という形で記述していましたが、その部分を上記にあるように.hasClass()
を利用してタイトルに特定のclass(今回のサンプルでは.is-open
)がなかったら非表示にするという内容に変更をします。
ここではクリック時にクラスが付加される動きというのもあり、classと.hasClass()
を利用する形で紹介しましたが、同じような条件分岐を用いれば例えばidやデータ属性で判断とかでも可能です。
アコーディオン -特定数に達していない場合は無効化する-
アコーディオンを実装する理由はいろいろあるとは思いますが、その中のひとつがコンテンツが多いページを初期表示ではすっきり見せたいからというのがあると思います。
ただ、例えば今度増える予定ではあるけど現状でコンテンツがまだ少ないのでわざわざ非表示にする必要がないなど、特定の数に達していない時にはアコーディオン機能を無効化したいという時は下記のように記述で実装することができます。
if ( $('.accordion dt').length > 2 ) {
$('.accordion dd').hide();
$('.accordion dt').on('click', function() {
$(this).toggleClass('is-open');
$(this).next().stop().slideToggle();
});
}
上記はアコーディオンのタイトルにあたる部分(ここではdt
)が3つ以上になった時にアコーディオンが機能し、それ以下の場合は機能しないという動きを実装できます。
制作者が静的HTMLを更新するとかほとんど更新がないようなものであれば単純にclassを外すとか組み直すなどすればいいですが、例えばCMSなどのような更新機能を使用しているとか表示数の増減が激しいサイトでこのような動きを実装したい時に使えると思います。
アコーディオン -開閉時にテキストを変更する-
アコーディオンである(開閉可能である)部分というのをユーザーに示すために、よくあるものだと通常時は下矢印のアイコンを表示させ、コンテンツ表示時はそのアイコンを上矢印にするといった見栄えがありますが、それらは先述した方法でアコーディオン開閉時にクラス操作を行っているので、そのクラスを用いて背景画像を切り替えるなどすれば容易に実装できます。
そういったものではなく、例えばデフォルト時には「OPEN」、コンテンツ表示時は「CLOSE」のように、アコーディオン開閉時に一部のテキストを変更するような動きを実装したい時は下記のように記述することで実装できます。
ここではサンプルとしてHTMLでdt
内にある<span>OPEN</span>
のテキストが変更されるもので、この「OPEN」というのがコンテンツ表示時の場合は「CLOSE」に変更されるようになります。
<dl class="accordion">
<dt>title 1 <span>OPEN</span></dt>
<dd>contents 1 ...</dd>
<dt>title 2 <span>OPEN</span></dt>
<dd>contents 2 ...</dd>
<dt>title 3 <span>OPEN</span></dt>
<dd>contents 3 ...</dd>
</dl>
var $acLabel = $('.accordion dt'),
openClass = 'is-open',
openText = 'OPEN',
closeText = 'CLOSE';
$acLabel.each(function() {
if ( $(this).hasClass(openClass) ) {
$(this).next().show();
$(this).find('span').text(closeText);
} else {
$(this).next().hide();
}
});
$acLabel.on('click', function() {
$(this).toggleClass(openClass);
$(this).next().stop().slideToggle();
if ( $(this).hasClass(openClass) ) {
$(this).find('span').text(closeText);
} else {
$(this).find('span').text(openText);
}
});
基本的な動きとしては「4. アコーディオン -特定のアコーディオンを初期表示で展開させておく-」で紹介したものを少し変更した感じになっており、.hasClass()
と開閉時にタイトルとなる部分に付加されるclassを利用していきます。
「classがついている = 展開されている」になるのでdt
にあるspan
のテキストを「CLOSE」に、逆に「classがついていない = 展開されていない」になるのでdt
にあるspan
のテキストを「OPEN」にすることで、開閉の状態によってテキストが変更される動きを実装することができます。
アコーディオン -コンテンツ内のボタンでも閉じれるようにする-
上で紹介してきたアコーディオンはいずれもタイトルにあたる部分をクリックすることでコンテンツ開閉の動きを実装してきましたが、こちらはコンテンツ内にアコーディオンを閉じる用のボタンを用意し、タイトルにあたる部分だけでなくこのボタンを押下することでもコンテンツ開閉できるようにしたものです。
実装にはそれぞれ下記のように記述し、ここではサンプルとしてHTMLで<span class="close">CLOSE</span>
となっている箇所がアコーディオンを閉じることができるボタンになります。
<dl class="accordion">
<dt>title 1</dt>
<dd>
contents 1 ...
<span class="close">CLOSE</span>
</dd>
<dt>title 2</dt>
<dd>
contents 2 ...
<span class="close">CLOSE</span>
</dd>
<dt>title 3</dt>
<dd>
contents 3 ...
<span class="close">CLOSE</span>
</dd>
</dl>
var $acLabel = $('.accordion dt'),
$closeButton = $('.close'),
openClass = 'is-open';
$acLabel.each(function() {
if ( $(this).hasClass(openClass) ) {
$(this).next().show();
} else {
$(this).next().hide();
}
});
$acLabel.on('click', function() {
$(this).toggleClass(openClass);
$(this).next().stop().slideToggle();
});
$closeButton.on('click', function() {
$(this).parent().prev().toggleClass(openClass);
$(this).parent().stop().slideToggle();
});
チェックボックスでチェックできる最大数を設定する
例えばチェックボックスは10個表示されているけれどチェックできる数は最大5個までにしたいといったように、チェックさせる数を制限したい時に使える方法です。
それぞれ下記のように記述することでチェックボックスに特定の数チェックを入れると他のチェックボックスをdisabled
にしてチェックできないようになり、最大数の指定はHTMLでハイライト表示しているdata-limit
で指定をします。
<div class="limit-checked" data-limit="5">
<input type="checkbox" name="foo" value="" />
<input type="checkbox" name="foo" value="" />
<input type="checkbox" name="foo" value="" />
・
・
・
</div>
$('.limit-checked').find('input[type="checkbox"]').on('change', function() {
var checkLimit = $(this).parent().attr('data-limit'),
checkedNum = $(this).parent().find('input[type="checkbox"]:checked').length,
$unchecked = $('input[type="checkbox"]:not(:checked)');
if ( checkedNum >= checkLimit ) {
$unchecked.prop('disabled', true);
} else {
$unchecked.prop('disabled', false);
}
});
ページ遷移するselect要素
JavaScriptでも短い記述で実装できるのでわざわざjQueryを使って実装する程のものでもないですが、select
の項目をそれぞれサイト名などにしておき、選択後にそのサイトに遷移する動きを実装する方法です。
実装にはそれぞれ下記のように記述し、option
のvalue
に記述したURLに遷移するようになります。
<select>
<option value="">選択してください</option>
<option value="https://www.google.co.jp/">Google</option>
<option value="https://twitter.com/">Twitter</option>
<option value="https://www.facebook.com/">Facebook</option>
<option value="https://dribbble.com/">Dribbble</option>
<option value="https://www.behance.net/">Behance</option>
</select>
$('select').on('change', function() {
var url = $(this).val();
if ( url != '' ) {
location.href = url;
}
});
ページ遷移するselect要素+α
上で紹介したものはselect
の項目を変更したらページ遷移するものでしたが、こちらはselect
の項目変更した時点ではページ遷移せずに、その下にあるリンク用テキストをクリックすることでselect
で選択した項目のページに遷移するというものになります。
<select>
<option value="">選択してください</option>
<option value="https://www.google.co.jp/">Google</option>
<option value="https://twitter.com/">Twitter</option>
<option value="https://www.facebook.com/">Facebook</option>
<option value="https://dribbble.com/">Dribbble</option>
<option value="https://www.behance.net/">Behance</option>
</select>
<a class="link" href="#">選択したリンク先へ</a>
$('select').on('change', function() {
var url = $(this).val();
if ( url != '' ) {
$('.link').attr('href', url);
} else {
$('.link').attr('href', '#');
}
});
その他のjQuery Snippetsに関しては下記ページから確認できます。