条件に応じて、違うクラスをタグに設定するJavaScript
同じレイアウトだけど、英語サイトでは違うクラスを設定して、独自のCSSをつけたいとかって時に使います。
実際に私もそんな状況があり、JavaScriptでなんとか自動化できないかと思っていました。なので、綺麗に書いたやつを紹介します。
実際のところそんなにコード量は多く無いんで、ライブラリやフレームワーク使うのは微妙と思いましたが、クソッタレIEがquerySelectorAll()をサポートしていなかったので、フレームワークで対応します。ちなみに私のはIE8で、対応してるってことらしいですが、使えませんでした。(なぜ?)
マイクロソフトはITの進化を遅らせているとかって言われますが(私だけですか?)、ウェブの人たちが味わってきた苦労はIE9で本当に解消されているのだろうか。
ま、それはさておき、まずはjQueryに対応したものを紹介しましょうか。以下のコードが実体(コア)になります。
/** * Conditional Class Namer for jQuery * * @copyright Tom Goodsun<http://www.tom-gs.com/> * @date 2010.10.13 */ var ConditionalClassNamer = function(className, fn) { this.className = className; if (typeof fn == 'function') this.getConditionalClassName = fn; var elements = $('.' + this.className); for (var i = 0; i < elements.length; i++) { var result = this.getConditionalClassName($(elements[i])); if (result != false && result != null) { $(elements[i]).addClass(this.className + '-' + result); } } } ConditionalClassNamer.prototype.info = { name: 'Conditional Class Namer', sign: 'ccn', version: '1.0' } ConditionalClassNamer.prototype.getConditionalClassName = function(element) { return this.info; }
jQueryに実装するとなんかうまくいかないので(やり方ミスってるかな、、、)、プロトタイプクラスを作ってみました。使い方はあとで紹介します。
続いて、Mootools対応版。
/** * Conditional Class Namer * * @copyright Tom Goodsun<http://www.tom-gs.com/> * @date 2010.10.13 */ var ConditionalClassNamer = new Class({ name: 'Conditional Class Namer', sign: 'ccn', version: '1.0', /** * Constructor * * String className * function fn(element) * Return string */ initialize: function(className, fn) { this.className = className; if (typeof fn == 'function') this.getConditionalClassName = fn; var elements = $$('.' + this.className); for (var i = 0; i < elements.length; i++) { var result = this.getConditionalClassName(elements[i]); if (result != false && result != null) { elements[i].addClass(this.className + '-' + result); } } }, /** * Custom funtion. * This must be something in String */ getConditionalClassName: function(element) { return this.sign; } });
こちらはMootoolsのクラスを作りました。それぞれ、このコードの前にフレームワークを読み込ませておいてください。
で、使い方です。両方共同じ使い方です。以下のコードをwindon.onloadイベントにでも登録しておけばひとまずOKです。
var a = new ConditionalClassNamer('change', function(element) { return 'goodsun'; }); var b = new ConditionalClassNamer('contactform-label', function(element) { return 'gs'; });
使い方なんですけどConditionalClassNamerクラスを生成するんですけど、コンストラクタの引数は2つで、以下のようになっています。
var ccn = new ConditionalClassNamer('対象とするクラス属性の値', function(element) { 判定条件を記述し、何か文字列を返します。 });
第2引数には関数を渡します。この関数は引数に対象としてリストアップされたそれぞれの要素がオブジェクトで入ってきます。そして、その関数の戻り値がfalseやnullでなければ、「指定したクラス名-関数の戻り値(文字列)」で新しくクラス名をその要素に設定します。
だから以下のような書き方ができます。
var ccn = new ConditionalClassNamer('locale', function(element) { var url = document.URL; if (url.match(/\/en\//)) { return 'en'; } else if (url.match(/\/ja\//)) { if (!element.hasClass('except-on-ja')) { return 'ja'; } } return null; })
ということです。