前置き
外部スタイルシートを使うとき、ひとつのHTML文書に複数の代替スタイルシートを指定することで、それらを切り替えて使うことが可能です。
この切り替えは、例えばNetscape6ではメニューの「表示>スタイルシート」で行えますが、残念ながら世間でシェアが最も多いブラウザであるMicrosoft Internet Explorerでは標準の機能にありません。
ところが「outsider reflex」(このサイトはデザインが格好いいので必見です)でMSIEでもスタイルシートを切り替られるスクリプトを紹介していました。
それに刺激を受けて、私も似たようなスクリプトを作ってみました。
ここで公開するスクリプトは、「三日坊主++の部屋」(現在は閉鎖)で公開されていた、MSIE5で代替スタイルシートを扱う方法を使わせて頂いています。
ソース
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head>
<link rel="alternate stylesheet" type="text/css" href="coolblue.css" title="クールブルー">
<link rel="alternate stylesheet" type="text/css" href="formal.css" title="フォーマル">
<link rel="stylesheet" type="text/css" href="simple.css" title="シンプル">
<link rel="stylesheet" type="text/css" href="none.css">
<script type="text/javascript" src="changess.js" charset="Shift_JIS"></script>
(中略)
</head>
<body>
<h1>おまけ</h1>
(中略)
<address>製作:いちゆう</address>
</body>
</html>
Javascript (changess.js)
/* スタイルシート切り替えスクリプト */
if ( document.styleSheets
&& !(navigator.userAgent.indexOf("Mac_PowerPC") != -1
&& navigator.userAgent.indexOf("MSIE 4") != -1)) {
/* Scriptでスタイルシートを扱えるブラウザのみ実行される */
/* 以下設定 */
label="スタイル選択:"; // 選択フォーム左の文字列
cdomain=".nifty.com"; // サイトのドメイン名
cpath="/critical/"; // サイトのパス
cdays=10; // クッキーの有効日数 0=ブラウザ終了まで
insertform=true;
/* 選択フォームを自動的に挿入するかどうか
true=挿入する
false=挿入しない(手動でフォームを書き込む) */
targetelement="address";
/* 選択フォームは、ここで指定した要素で一番最初に現れるものの
直前に挿入される(自動的に挿入するとき) */
addss=true;
/* スタイルシートを追加するかどうか
true=追加する
false=追加しない */
addstyles=new Array(
'初夏' , 'http://homepage1.nifty.com/critical/summer.css' ,
'ノート' , 'http://homepage1.nifty.com/critical/notebook.css' );
/* 追加するスタイルシートを名前とURLの組で指定する */
/* 以上設定 */
main();
}
function main(){
/* メイン関数 */
N6 = navigator.product == "Gecko";
sfTitles="";
writeafter=false;
if(addss) {
userstyles = fGetCookie('userstyles');
if (userstyles!='noCookie') {
var addstylesstring = addstyles.join(',') + ',' + userstyles;
addstyles = addstylesstring.split(',');
}
for (i=0; i < addstyles.length; i+=2){
fAddLink(addstyles[i+1], addstyles[i]);
}
}
sheet = fGetCookie('sheet');
if(!N6){
/* Mozillaでないとき、スタイルシートの一覧を取得し既定のスタイルに切り替える */
fGetStyleTitles();
if(sfTitles.indexOf(sheet)==-1) sheet=sS[0].title;
fChangeSS(sheet);
}
else if(sheet!="noCookie")
document.write('<META http-equiv="Default-Style" content="'+ sheet +'">');
/* Mozillaのとき、最初にスタイルシートの一覧を取得すると不具合を生じるので、
meta要素で既定のスタイルを設定する */
window.onload=fInit;
window.onunload=fEnd;
}
function fGetStyleTitles(){
/* スタイルシートの一覧を取得 */
sS=document.styleSheets;
for(i=0; i<sS.length; i++){
if (sS[i].title){
if (sfTitles.indexOf(sS[i].title)==-1) {
sfTitles+=sS[i].title;
sfTitles+=",";
}
}
}
sfTitles+="なし";
sfTitle=sfTitles.split(",");
}
function fGetCookie(cName){
/* クッキーを取得 */
var c=document.cookie, a, b;
if(c.indexOf(cName + '=')!=-1){
a=c.indexOf(cName + '=');
b=c.indexOf(';',a+cName.length+1);
if(b==-1) b=c.length;
return unescape(c.substring(a+cName.length+1,b));
}
return 'noCookie';
}
function fSetCookie(cName,cTitle){
/* クッキーを設定 */
var eTitle=escape(cTitle), c;
var cexpires=new Date();
if (cTitle!='')
cexpires.setTime(cexpires.getTime() + 1000*60*60*24*cdays);
else
cexpires.setTime(cexpires.getTime() - 1000*60*60*24);
c = cName + '=' + eTitle + '; domain=' + cdomain + '; path=' + cpath
+ ((cdays!=0)?('; expires=' + cexpires.toGMTString()):';') ;
document.cookie=c;
}
function fChangeSS(ssTitle){
/* スタイルシートの動的切り替え */
if(!document.styleSheets) return;
for(i=0; i<sS.length; i++)
sS[i].disabled = ((sS[i].title==ssTitle)||(!sS[i].title)) ?
false : true;
fSetCookie('sheet',ssTitle);
}
function fSelectSS(obj){
/* 選択されたスタイルシートに切り替える */
var index=obj.selectedIndex;
sheet=obj.value;
fChangeSS(sheet);
window.focus();
obj.selectedIndex=index;
}
function fInit(){
/* ページが読み込まれたときの処理 */
if(N6){
/* Mozillaのとき、ここでスタイルシートの一覧を取得する */
fGetStyleTitles();
if(sfTitles.indexOf(sheet)==-1) sheet=sS[0].title;
fChangeSS(sheet);
}
if (insertform) fAddForm();
if (writeafter) fWriteAfter();
}
function fAddForm(){
/* 選択フォームを追加する */
var obj;
if(document.all)
obj=document.all.tags(targetelement).item(0);
else if(document.getElementsByTagName)
obj=document.getElementsByTagName(targetelement).item(0);
if(!obj) return;
fMakeHTML();
if(document.all)
obj.insertAdjacentHTML('beforeBegin',
'<div class="selectsheet">'+nHTML+'</div>');
else{
var nDIV=document.createElement('DIV');
nDIV.innerHTML=nHTML;
nDIV.className="selectsheet";
obj.parentNode.insertBefore(nDIV, obj);
}
}
function fMakeHTML(){
/* 選択フォームのHTMLを作成する */
nHTML='<label>' + label +
'<select name="selectss" onchange="fSelectSS(this);">';
for(i=0; i<sfTitle.length; i++){
nHTML+='<option value="';
nHTML+=sfTitle[i];
nHTML+=(sfTitle[i]==sheet) ? '" selected="selected">' : '">';
nHTML+=sfTitle[i];
nHTML+='</option>';
}
nHTML+='</select></label>';
}
function fWriteForm(){
/* 選択フォームを書き出す */
if(document.styleSheets){
if(!N6){
fMakeHTML();
document.write('<div class="selectsheet">',nHTML,'</div>');
} else {
document.write('<div class="selectsheet" id="selectform"></div>');
writeafter=true;
}
}
}
function fWriteAfter(){
/* 選択フォームの中身を後で生成(Gecko用) */
var obj;
obj=document.getElementById("selectform");
if(!obj) return;
fMakeHTML();
obj.innerHTML=nHTML;
}
function fEnd(){
/* 終了処理 */
fReadSS();
if (NowSheet!=sheet) fSetCookie('sheet',NowSheet);
}
function fReadSS(){
/* 現在適用されているスタイルシートを読み込む */
NowSheet="none";
for(i=0; i<sS.length; i++) {
if ((!sS[i].disabled)&&(sS[i].title)) NowSheet=sS[i].title;
}
}
/* スタイルシート追加 */
function fAddLink(ssurl, sstitle){
if(document.all){
var nLink=document.createStyleSheet(ssurl);
nLink.title=sstitle;
nLink.disabled=true;
}
else if(document.styleSheets){
var nLink=document.createElement('LINK');
nLink.rel="alternate stylesheet";
nLink.type="text/css";
nLink.href=ssurl;
nLink.title=sstitle;
var oHEAD=document.getElementsByTagName('HEAD').item(0);
oHEAD.appendChild(nLink);
}
}
ダウンロード(クッキー書き換え用HTML付き) cssselect.lzh
使い方
読み込ませたいスタイルシートは、Netscape6のときと同じようにLINK要素で指定します。TITLE属性がフォームの選択肢になります。
標準のスタイルシートは一番最初に置いてください。スクリプトが有効な環境(IE5やNetscape6でJavascript有効)では、最初は一番上の(代替)スタイルシートが適用されます。
Javascript無効、もしくはNN4等の場合、LINK要素で通常のスタイルシートとして指定されているものが適用されます。
スクリプトを読み込むSCRIPT要素はスタイルシートを読み込むLINK要素の後に置いてください。
自動的に選択フォームを挿入するときは、ソースの最初の部分の変数insertformにtrueを代入し、変数targetelementには直前にフォームを挿入する要素名を代入してください。上の例では、ページが読み込まれた後にADDRESS要素の直前に選択フォームが挿入されます。この場合HTML文書のBODY要素に手を加える必要はありません。
手動で選択フォームを挿入するときは、ソースの最初の部分の変数insertformにfalseを代入し、BODY要素内の選択フォームを置きたい場所に、
<script type="text/javascript" > <!-- fWriteForm(); // --> </script>
というSCRIPT要素を書き加えてください。
変数cdomainには設置するサイトのドメイン名を、変数cpathにはパスを、変数cdaysにはクッキーの有効日数を代入してください。これらの値はクッキーの適用範囲を決めるために用います。
選択したスタイルシートはクッキーに記録され、ページを移動しても保存されます。サイト内であれば前のページと同じTITLE属性のスタイルシートが引き継がれます。ひとつのサイト内ではスタイルシートのTITLE属性の組み合わせを統一しておいたほうがよいでしょう。
HTMLに記述した他にスタイルシートを追加するときは、変数addssにtrueを代入して配列変数addstylesにスタイル名、スタイルのURLの順の組み合わせで記述します。スタイルシートの追加を行わないときは変数addssにfalseを代入してください。
クッキーを利用して閲覧者の指定したスタイルシートを追加することができます。→追加用ページ ただしNetscape6やMozillaでは現在のところ動きません。
tDiaryでこのスクリプトを使う場合は、
# changecss.rb def css_tag if @theme and @theme.length > 0 then css = "#{theme_url}/#{@theme}.css" else css = @css end <<-CSS <meta http-equiv="content-style-type" content="text/css"> <link rel="stylesheet" href="#{css}" type="text/css" title="default" media="all"> <script type="text/javascript" src="plugin/changess.js" charset="Shift_JIS"></script> CSS end
という内容のファイルをchangess.rbとしてchangess.jsと一緒にpluginディレクトリに入れるのが簡単な方法だと思います。要はSCRIPT要素と、LINK要素のTITLE属性が入ればいいです。詳しくは、tDiaryのプラグインの作り方を参照してください。
注意
このスクリプトの動作はWindowsのIE6及びMozilla1.0で確認しています。また、以前MacのIE5と、LinuxのMozilla0.9.8で動作しているのを確認しました。おそらくIE5以降、またNetscape6以降で動作するものと思います。そのほかの環境については確認していませんが、Operaでは動作しないらしいです。
このスクリプトについて権利を主張するつもりはありません。コピーしたり改造したりし使ったり配布したりするのはご自由にどうぞ。
応用例
このスクリプトをお使いになっているサイトをリンク集にて紹介させていただいております。
更新履歴
- 2003年6月16日
Mozillaで手動挿入した選択フォームが表示されない場合がある不具合を改善しました。
tDiaryでの利用について加筆しました。
- 2002年9月29日
リンクを別ページに分離しました。
- 2002年8月5日
リンクを整理し、応用例として、「amemix 〜フリーゲーム製作&配布サイト〜」、「[flow] RC3.01」、「ラクガキgarden」、「Le Mode」を追加しました。
- 2002年4月10日
応用例として、「津 波 荘」、「Obimatsu Web」、「怠慢堂本舗」に、関連サイトとして「なぞぺーじ」にリンクを追加しました。
- 2002年2月21日
スクリプトでスタイルシートの追加を行なえるようにしました。クッキーを利用して閲覧者の指定したスタイルシートも追加できます。
- 2002年1月12日
湾岸道さんの「Crime Claim Shower」移転。
- 2002年1月2日
応用例として、「ほーむぺーじ厨房」を新たに紹介しました。
- 2002年1月1日
応用例として、湾岸道さんのサイト「Crime Claim Shower」、および関連サイトを新たに紹介しました。
- 2001年12月8日
応用例として、motosenさんのサイトを紹介しました。
- 2001年8月9日
Mozillaのメニューからスタイルシートを選びなおしても次に引き継がれるようにしました。また、ちょっぴり汎用っぽくしました。
- 2001年6月15日
「三日坊主++の部屋」の記事を参考に、Netscape6で全部のスタイルが表示されるようにした。