2012/06/20

"ui-icon-alt"を使う2つの方法|jQuery Mobile

jQuery Mobileのデザインを作ることができるThemeRollerでダウンロードしたCSSの中に .ui-icon-alt というセレクタを見つけた。

/* Alt icon color
-------------------------------------*/
.ui-icon-alt {
 background: #fff;
 background: rgba(255,255,255,.3);
 background-image: url(images/icons-18-black.png);
 background-repeat: no-repeat;
}

どうやら色違いのアイコンを設定できるようだ。

jQuery MobileのDocs内にはアイコンの切替(Alt icon color)についての記述はないようなので、
ThemeRoller独自に拡張されたものなのだろうか。
ui-icon-alt」などで検索してみたけれども、それらしき情報も見つからない。

ということで、実装する方法をいろいろ試してみた結果、応用が効きそうな2つをご紹介。
ただし、一部のフォーム要素には非対応


個別の要素ごとに Alt icon color を設定する方法



アイコンを設定する時は、対象の要素にdata-icon="***"を指定する。
jQuery Mobileはアイコンを描写するために、指定された要素の内部に新たな要素を生成し、
"ui-icon-***"をクラスとして(class="ui-icon-***"を)追加する。

そこでdata-icon="aaa bbb"と半角スペースを挟んで2つの文字列を指定してあげると、
生成される要素にはclass="ui-icon-aaa bbb"が付与され、2つのクラスを追加する事ができる。

つまり、半角スペースの後を ui-icon-alt にしてアイコンを指定すると、
生成される要素に ui-icon-alt のクラスを付与させることができる。

ただ、なんかちょっとずるい感じがするな。。。

sample1:個別の要素ごとにアイコンの色を設定
右側のボタンに『data-icon="*** ui-icon-alt"』を設定

<div class="ui-grid-a">
 <div class="ui-block-a">
  <h3>Normal</h3>
  <a data-role="button" data-icon="check">check</a>
  <a data-role="button" data-icon="gear">grid</a>
  <a data-role="button" data-icon="refresh">refresh</a>
  <a data-role="button" data-icon="grid">grid</a>
  <a data-role="button" data-icon="star">star</a>
 </div>
 <div class="ui-block-b">
  <h3>Icon-Alt</h3>
  <a data-role="button" data-icon="check ui-icon-alt">check</a>
  <a data-role="button" data-icon="gear ui-icon-alt">grid</a>
  <a data-role="button" data-icon="refresh ui-icon-alt">refresh</a>
  <a data-role="button" data-icon="grid ui-icon-alt">grid</a>
  <a data-role="button" data-icon="star ui-icon-alt">star</a>
 </div>
</div>


テーマごとに Alt icon color を設定する方法



アイコンの背景を透明にした場合、テーマによってはアイコンが見えづらくなってしまう。
任意のテーマ内全てのアイコンに対して個別の設定をするのは結構大変。
jQueryを使いテーマを指定して内部のアイコンを一括で設定してしまおう。

sanple2.jsだけでは、Ajaxで読込んだページには適用されないので、
本当は$('div:jqmData(role="page")')の pageinit イベントなんかにバインドしてあげたほうがよい。

sample2:テーマごとにアイコンの色を設定
明度の高いc、d、eのテーマに黒いアイコンを設定

$(function(){
 var $alttheme = new Array( "c", "d", "e" ); //ここでテーマを指定
 var at = new Array();
 for( t in $alttheme ){
  at.push(':jqmData(theme="' + alttheme[t] + '"):jqmData(icon) > span > span');
 }
 $(at.join()).addClass('ui-icon-alt');
});
<div data-role="header" data-theme="a">
 <h1>theme a</h1>
 <a data-icon="arrow-l">button a</a>
 <a data-theme="b" data-icon="arrow-r" data-iconpos="right">button b</a>
</div> 
<div data-role="header" data-theme="b">
 <h1>theme b</h1>
 <a data-icon="arrow-l">button b</a>
 <a data-theme="c" data-icon="arrow-r" data-iconpos="right">button c</a>
</div> 
<div data-role="header" data-theme="c">
 <h1>theme c</h1>
 <a data-icon="arrow-l">button c</a>
 <a data-theme="d" data-icon="arrow-r" data-iconpos="right">button d</a>
</div> 
<div data-role="header" data-theme="d">
 <h1>theme d</h1>
 <a data-icon="arrow-l">button d</a>
 <a data-theme="e" data-icon="arrow-r" data-iconpos="right">button e</a>
</div> 
<div data-role="header" data-theme="e">
 <h1>theme e</h1>
 <a data-icon="arrow-l">button e</a>
 <a data-theme="a" data-icon="arrow-r" data-iconpos="right">button a</a>
</div> 



※ 一部フォーム要素には非対応



jQuery Mobileはsample3-1.htmlのようなマークアップからsample3-2.htmlを生成する。
<a href="#" data-role="button" data-icon="check">sample<a>
<a href="#" data-role="button" data-icon="check" class="ui-btn ui-btn-icon-left">
 <span class="ui-btn-inner ui-btn-corner-all">
  <span class="ui-btn-text">sample</span>
  <span class="ui-icon ui-icon-check ui-icon-shadow"> </span>
 </span>
</a>


上記の2つの方法はこの生成されるマークアップ構造を利用して Alt icon color を実装している。
そのためアイコンを描写するマークアップが異なる次の3つのフォーム要素は非対応となってしまう。

  • <input type="radio" />
  • <input type="checkbox" />
  • <input type="search" /> ※入力内容削除ボタンには有効


ラジオボタン・チェックボックスがON時に表示されるアイコンの色は、ThemeRoller内でも白固定で指定することができない。
全テーマ共通の設定になるので、アクティブカラーをある程度明度の低い色にしておけば特に問題はないだろう。

ただし、検索タイプのインプットに関しては、アイコンの背景を透明にした場合に致命的な問題が起こる。
jQuery Mobileが「ここは検索タイプ」と分かりやすいようにしてくれているのに、
虫眼鏡アイコンが外側の要素の背景に溶け込んでしまいほとんど見えなくなってしまう。

CSSを修正とjavascript追加で解決できなくはないんだけど、
CSSはいじらないで実装したいので、もうちょっと勉強してきます!