スタイルシートをまとめて動的に設定する
JavascriptでCSSを動的に設定するとき、普通は次のようにしますね。
document.getElementById("hoge").style.display = "none";
IDでelementを取得し、そのstyleのdisplayにnoneを設定・・・って正直面倒っちいです。
いっぱい設定しようと思ったら、一行一行書かないといけないし、
classに同じスタイルを設定しようと思ったら、ノードをfor文で回してclassを見て・・・気が遠くなります。
そんなときはelementにスタイルを設定するのではなく、動的にスタイルシートを追加しましょう。
var css = (function() { var s = document.createElement('style'); s.setAttribute("type", "text/css"); document.getElementsByTagName('head').item(0).appendChild(s); var ss = s.sheet; return function(sel, sty) { ss.insertRule(sel + "{" + sty + "}", 0); }; })();
使い方も簡単、第一引数にセレクタ、第二引数にスタイルを入れます。
普通のスタイルシートと基本的にはおんなじ書き方で使えます。
css("#hoge", "display: none;"); css(".piyo", "background: gray; width: 50%;");
何となく解説
基本的には無名関数とクロージャです。
いいですね、クロージャ。
Javascriptのトリッキーさの先駆けみたいな感じがして好きです。
しかしクロージャについて説明するのとってもモニョモニョするので、ぜひ自分で調べてください。
僕はこちらを見て何となく理解しました。
[JavaScript] 猿でもわかるクロージャ超入門 1 問題 · DQNEO起業日記
JAVAでいうとPrivateなメンバやメソッドを操作できる、staticなメソッドを公開できるようなものかなーと。
多分違うけど。
どっちにしろこれJava知らない人には全然伝わんないと思います。
まあその程度の理解なので、間違っていたら指摘してください。
あ、そんな私の仕事の種であるJavaにはクロージャはありません。
Java7で採用されると思ったけど、そんなことは無かったぜ!
さて、まずはcreateElementで<style>要素を作ります。
それにtype属性をつけて<style type="text/css">を作ります。
var s = document.createElement('style'); s.setAttribute("type", "text/css");
それを<head>の子要素として追加します。
getElementsByTagNameの戻り値は配列(2012/5/3追記:これは配列ではなくNodeListオブジェクトですね。コメントにて指摘頂きました。ありがとうございます)ですが、<head>は必ず一つだけなのでitem(0)とします。
<style>のsheetを変数ssに入れます。
これがスタイルシートオブジェクトです。
document.getElementsByTagName('head').item(0).appendChild(s); var ss = s.sheet;
css("", "")で実行されるのが次のクロージャ部分です。
外側からはこの内部しか見えませんが、クロージャの中からは一つ外側のssオブジェクトが見えるわけです。
これをレキシカルスコープといいます。
return function(sel, sty) { ss.insertRule(sel + "{" + sty + "}", 0); };
あとは最後にfunctionの無名関数を()();で囲んで即実体化してます。
CSSのインスタンスは複数はいりませんから、これでオブジェクトの実体を一つだけに制限します。
JavaでいうSingletonに近いのかな。