jQueryで複数要素の中から最も広い横幅の値を取得する
要素のコンテンツ量が違いがあっても、左揃えのレイアウトで見た目をデザインしていくこともありますが、デザインによっては対象の要素の最大幅でレイアウト調整する必要が出てきます。
WordPress等のCMSであれば、投稿の内容によって幅が変わることもあり、ある程度の幅で固定してスタイルを指定をすると、もしそれ以上のコンテンツ量になれば表示崩れはおきます。
JavaScriptや簡易にプログラムが書けるjQueryを使うことで、対象の要素の幅の最大値を求めてデザインを調整することができます。
要素の中から最も広い横幅の値を取得
サンプルとして、管理番号や製品番号なども含めてリスト表示するとしましょう。
HTMLの構造は以下のように構築してみます。
HTML
<ul class="sample-list">
<li><span>a-1</span>Text... text... text... text...</li>
<li><span>a-2.</span>Text... text... text... text...</li>
<li><span>b-16.</span>Text... text... text... text...</li>
<li><span>b-102.</span>Text... text... text... text...</li>
<li><span>c-23.</span>Text... text... text... text...</li>
<li><span>c-27.</span>Text... text... text... text...</li>
</ul>
レイアウト調整をしなければ、コンテンツは左に詰めて表示されます。
番号部分のspan要素は、コンテンツの文字数によって自動で幅が調整できると便利です。
文字数が1番多い要素に合わせて幅をとり、左寄せで整えていきたいところです。
CSSでは、レイアウトを調整するためのスタイルをあてます。
CSS
.sample-list {
list-style: none;
}
.sample-list span {
display: inline-block;
margin: 0 0.3rem 0 0;
}
span要素はコンテンツ量でブロックとするよう「display: inline-block;」とします。
このあと、jQueryを使ってspan要素に幅を設定していきます。
続いて、JSのプログラムを見ていきましょう。
jQueryではまず、
Function.prototype.applyで、配列オブジェクトの引数を用いて関数を呼び出します。
Math.max関数とapplyメソッドを使います。
Math.max.applyとすることで、配列から最大値を返してくれます。
構文
Math.max.apply(null, array)
引数は、「null」でグローバルオブジェクトとしておき、配列(array)から最大値を取得します。
ちなみに、最長値を取得する場合はMath.min関数になります。
以下、jQueryのプログラムになります。
jQuery
$(window).on("load", function(){
let wList = new Array();
$(".sample-list span").each(function(index){
wList[index] = $(this).width();
});
let maxW = Math.max.apply(null, wList);
$(".sample-list span").css({"width":maxW+"px"});
});
空の配列オブジェクトの変数「wList」を作成してから、each関数の処理で「wList[index] = $(this).width();」として、対象の要素の幅の配列を作成していきます。
変数「maxW」には、配列から最大値を取得して格納します。
最後に、要素に対してcssメソッドで最大値の幅をWidthプロパティの値とします。
実装してみますと、1番広い要素に合わせた幅が適応されているのが確認できます。
これで、情報を追加する際に番号の桁数が増えても、自動で幅を調整していくことができます。
表示・非表示の動作を含む場合
ボタンをクリックしてから表示されるコンテンツであったり、アコーディオンなどの開閉式で非表示にしているコンテンツを展開して表示する場合は、うまく動かないこともあります。
要素は残しつつ非表示にする「visibility: hidden;」で表示を調整しているのであれば問題ありませんが、要素ごと非表示にする「display: none;」で表示を調整している場合は、要素の幅を取得することができません。
そのような場合は、クリックしてから幅を取得するようにしていきます。
サンプルとして、ボタンをクリックしてコンテンツを表示する場合で見ていきます。
まずはHTML。
先ほどのコードからbutton要素を追加しています。
HTML
<button class="list-btn">List</button>
<ul class="sample-list">
<li><span>a-1</span>Text... text... text... text...</li>
<li><span>a-2.</span>Text... text... text... text...</li>
<li><span>b-16.</span>Text... text... text... text...</li>
<li><span>b-102.</span>Text... text... text... text...</li>
<li><span>c-23.</span>Text... text... text... text...</li>
<li><span>c-27.</span>Text... text... text... text...</li>
</ul>
CSSでは、リストを「display: none;」として、最初は要素ごと非表示にしています。
CSS
.sample-list {
list-style: none;
display: none;
}
.sample-list span {
display: inline-block;
margin: 0 0.3rem 0 0;
}
button {
margin: 1rem;
}
うまくいかない例も一緒に見てみましょう。
以下は、値が取得できない場合のプログラムです。
jQuery
$(window).on("load", function(){
let wList = new Array();
$(".sample-list span").each(function(index){
wList[index] = $(this).width();
});
let maxW = Math.max.apply(null, wList);
$(".sample-list span").css({"width":maxW+"px"});
});
$(function() {
$(".list-btn").on("click", function(){
$(".sample-list").not(":animated").slideToggle();
});
});
ボタンをクリックしてコンテンツを表示した時、要素ごと非表示であったため幅が取得できず、span要素の幅は0(width:0px;)となり表示は崩れます。
ボタンやアコーディオンなどで展開表示する場合は、on(“load”) 関数ではなくon(“click”) 関数で幅を取得する処理を実行します。
jQuery
$(function() {
$(".list-btn").on("click", function(){
$(".sample-list").not(":animated").slideToggle();
let wList=new Array();
$(".sample-list span").each(function(index){
wList[index] = $(this).width();
});
let maxW = Math.max.apply(null, wList);
$(".sample-list span").css({"width":maxW+"px"});
});
});
今回のサンプルでいくと、slideToggleメソッドで表示させてからその後のプログラムで幅を取得し、span要素に最大値の値を適応させています。
実装してみますと、しっかり幅が設定されているのが確認できます。
どの方法で表示の調整しているかで、Webページがロードしたタイミングか、または開閉に必要なボタンをクリックしたタイミングかが変わってきます。
また、今回のサンプルのようなパターンでなくても、どこかの要素の最大値を取得して、その値で別の部分のデザインを調整するような時でも活用できます。
自動で幅が取得できると便利なこともありますので、Math.max関数やMath.min関数を知っておくと良いでしょう。