(旧)コダフォンの日記ブログ(移転しました)

FC2ブログに移転しました。ここいる?

変数でjQueryのCSSメソッドに値を指定する方法

https://unskilled.site/jquery-css-variable/

変数でjQueryCSSメソッドに値を指定する方法

jQuerycssメソッド

jQueryで割と多く使われるのはcssメソッドではないでしょうか?

$( ".hoge" ).css( "width" , "100px" );

jQueryの使用動機は、cssの編集に起因する事が多いと思います。@MINOも最初はcssをいじりたいからjQueryを勉強し始めました。

jQuerycssメソッドで変数を使う方法は、javascriptにもjQueryにも慣れていなかった@MINOがつまずいたところです。これからjQueryを覚えたいという人はぜひ読んでいただきたいと思います。

jQuerycssメソッドは文字列リテラルを使う

jQuerycssメソッド

jQuerycssメソッドでは「セレクタ」、「プロパティ」、「プロパティの値」を指定する形になっています。(セレクタの指定はjQueryメソッドなので厳密にいうとこの説明は合っていないが気にしない)

文字列リテラル

各指定は「文字列リテラル」で行われています。文字列リテラルとは「文字列として解釈される書式で記述された値」のことを言いいます。javascriptでは通常であれば[“]や[‘]で囲まれているのは文字列リテラルとなります。

すこし語弊があるが、jQuerycssメソッドは「文章」を使って値を指定すると言えます。

hoge”や”width”や”100px”は文字列リテラルで文章というわけデス。

変数を用いた場合

簡単な例

つまり変数を用いる場合でも最終的に指定が「文章」になっていればいいのですね。

var hogeWidth = $( "body" ).width() * 0.5;

$( ".hoge" ).css( "width" , hogeWidth );

この例は最も単純な例だ。bodyのwidthを取得して、0.5を掛けたものをhogeWidthに格納して、それを.hogeのwidthの値として指定しています。

jQueryの内部処理についての注意点

ここで注意が必要ですが、width()で取得できる値は文字列リテラルではなく、数値です。だからhogeWidthに入っている値は数値型(数値リテラル)のはずだ。例ではそれをそのまま指定しています。

さっきjQuerycssメソッドでは文字列リテラルを使うと説明していたのにおかしいではないかと思われるかもしれません。

これについては、単に数値型として指定された場合に、jQueryの中で”px”をつけて文字列にするという処理が行われていることに起因します。

だから数値で指定しても問題がないのです。つまり以下のような事をjQueryがやってくれているという訳なんですね。

//hogeWidthは末尾に"px"が付いていることで文字列リテラルになる

var hogeWidth = ( $( "body" ).width() * 0.5 ) + "px";

$( ".hoge" ).css( "width" , hogeWidth );

例えば、bodyが800pxだとしたら、$( “body” ).width() * 0.5 は400となる。これに”px”が付くので、”400px”という文字列リテラルが hogeWidthに代入されるということになる。

任意の単位を付けたいときは

しかし”px”が自動で付いてくれるのはありがたいですが、”px”ばかりではなく”%”や”em”など指定したい単位はいろいろあるはずです。

その為には「文章を作る」ことで指定が可能になります。上記の例のように任意の単位を変数につなげてしまうのです。

そうすれば文字数リテラルになるので、値の指定ができます。

var hogeWidth = ( ( $( "#main" ).width() / $( "body" ).width() ) * 100 ) + "%";

$( ".hoge" ).css( "width" , hogeWidth );

上記の例ではbodyのwidth値で#mainのwidth値を割ってその答えに”%”を付けています。”70%”とか”80%”といったような文字列リテラル、すなわち文章がhogeWidthに代入されることになります。

複数の値の一括指定の場合は

marginなどのように上下左右の値を一括で指定できるプロパティもあります。この場合はどうしたらいいのでしょうか。通常では文字列リテラルだと以下の様な形になります。

//普通に文字列リテラルで指定した場合

$( ".hoge" ).css( "margin" , "10px 10px 5px 3px" );

margin-topの指定だけ変数にしたいという場合を想定した場合次のような書き方ができます。

//変数に格納してから指定

var hogeMargin = ( $( ".hoge" ).width() * 0.1 ) + "px 10px 5px 3px"

$( ".hoge" ).css( "margin" , hogeMargin );

//直接指定

$( ".hoge" ).css( "margin" , ( $( ".hoge" ).width() * 0.1 ) + "px 10px 5px 3px" );

$( “.hoge” ).width() * 0.1 の答えに”px 10px 5px 3px”をくっつけているだけです。変数に代入しなくても、直接式を記述しても構わないです。

これで”12px 10px 5px 3px”とか”8px 10px 5px 3px”とかという文字数リテラルがhogeMarginに代入される事になりますよ。

複数の値の一括指定の応用

さらに例を挙げます。今度はmargin-topとmargin-leftの指定を変数にしたい場合は以下のようになります。

//変数に格納してから指定

var hogeMargin = ( $( ".hoge" ).width() * 0.1 ) + "px "+ ( $( ".hoge" ).width() * 0.2 ) + "px 5px 3px"

//直接指定

$( ".hoge" ).css( "margin" , ( $( ".hoge" ).width() * 0.1 ) + "px "+ ( $( ".hoge" ).width() * 0.2 ) + "px 5px 3px" );

これも全部つなげているだけ。気を付けてほしいのが、( $( “.hoge” ).width() * 0.1 )の後のpxの後ろには半角空白がある点です。

なんで必要かお分かりでしょうか?

これが無いと、hogeMarginに代入されるのは以下のようになってしまうのです。

“6px12px 5px 3px”

これではmargin-topとmargin-leftの値がくっついてしまっているので、cssの値の指定としてはエラーになり、cssは適用されません。

変数を用いる時は、正しい形の文字列リテラルと「同じ文章」にすることが大事なんですね。だから空白も適切に繋いであげなければならないのです。

セレクタもプロパティも文字列リテラル

セレクタもプロパティの指定にも変数を使うことが可能です。今までの説明と同じように文字列リテラルを作れればOKです。

$(window).on("ready" , function(){

var bodyWidth = $( "body" ).width();

var hogeClass = ["Postlist","Article","Index","Catgory"];

var propertys = ["width","height"];

var amount = ["20px","30px","40px","50px"];

var widths = [];

var sw,i=0;

if( bodyWidth > 900 ){

sw = 0;

}else{

sw = 1;

}

for ( ; i < hogeClass.length ; i++ ){

//セレクター、プロパティ、プロパティの値すべて変数による指定

widths[i] = $( ".hoge" + hogeClass[i] ).css( propertys[sw] , amount[i] );

}

});

すこし複雑に見えるが、やっている事は簡単です。配列に格納している文字列と”.hoge”をつなげてセレクタ文章を作っています。

またwidthとheightのプロパティも配列に格納して bodyのwidthの条件でどちらにするかを決めています。最終的にはfor文を回して、これまたあらかじめ配列に入れてある値を指定しています。

この例には実用性はほとんどないですが、セレクタやプロパティを変数で動的に指定できるという可能性がありますよ。

まとめ

変数指定が思うように使えるようになってから、jQueryでやれることも大きくひろがった記憶があります。

@MINOは最初文字列リテラルの意味さえ分からなかったので、marginの値の指定などはどうしたらいいのかさっぱりわからなかったデス。

一括指定がどうしてもできないから、効率が悪いなと思いながらもmargin-topなどに分けて指定していたほどですよ。

そのうち「あ、なるほど」とおもえる瞬間がきて、一気に理解が深まる瞬間があります。

そのお手伝いがこの記事で出来たら@MINOとしてはうれしいでっす。