GWTで動的にスタイルシートを変更する、その2

GWTで動的にスタイルシートを変更するの続きであり、GWTによって動的にスタイルシートを変更する方法であるが、しかし、特にGWTに限らない、ごく普通にJavaScriptで可能な方法である。

ゴール:ユーザからの指示のあったその場で動的にスタイルシート(CSS)を変更する

ユーザが何らかの操作を行ったら、その場でスタイルシートを変更する。例えば、色テーマを完全に変更してしまい、白基調から黒基調にするといったようなことだ。

動的スタイルシート変更の概要

非常に簡単だ。

  • HTML中で特定のスタイルシートへのlinkを作成する。
  • 上記リンクによって呼び出すスタイルシートを静的ファイルではなく、サーブレット(あるいはCGI)とする。
  • 先のlinkタグの内容を動的に変更する。

HTML中にスタイルシートへのlinkを置く

単純だ、例えば以下のように記述する。

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css" id="dynamicStyleSheet">
</head>
<body>
</body>
</html>

cssは、サーブレットでも何でも良い。サーバ側でスタイルシートを生成して返すものであればよい。

Linkタグをプログラムで処理する

idを目標として上記のlinkタグをプログラムで取得しておき、ユーザがテーマ変更を指示したら、hrefの中身を書き換えてやればよい。GWTでやるとなると以下だが、JavaScriptでも大した操作ではないだろう。

import java.util.*;

import com.google.gwt.dom.client.*;

public class CssChanger {  
  private static LinkElement link;  

  public static void initialize() {
    link = LinkElement.as(Document.get().getElementById("dynamicStyleSheet"));    
  }
  public static void setName(String name) {
    link.setHref("css?name=" + name + "&timestamp=" + new Date().getTime());
  }
}

初期化時にinitialize()を呼び出し、linkタグを取得しておき、テーマ変更時にはテーマ名を指定してやり、hrefを例えば、「css?name=sample&timestamp=45786921245457845」などに置き換える。

timestampがある理由は、どうあってもブラウザ側にキャッシュされないようにである。特にキャッシュされない方策がしてあるなら、「css?name=sample」でよい。

サーバ側

サーバ側でやることは簡単だ。nameパラメータとしてテーマ名を受け取るので、対応するスタイルシートを送り出してやればいいだけになる。