MozTips

Contents

はじめに

スタイルシートを切り替える

適用されているスタイルを取り出す

透明度を変える

ボーダ枠の形状を変える

アウトライン枠を変える

フレームの内容を取り出す

テキスト入力の文字を選択する

要素を表示領域に移動する

表示領域をページのサイズに変更する

JSファイルの文字コードを指定する

スクリプトソースを切り替える

コンテキストメニューを作る

モーダルウィンドウをポップアップする

サイドバーにページを登録する


はじめに

Mozilla も正版がリリースされた(2002年 6月)ので、ここで食えない事情でも... と思ったのですが、 Mozilla は現在(2002年)約90日のペースでバージョンアップをしている関係上、 「食えない事情」はすぐに陳腐化してしまう恐れがあります(笑)

そこで、Mozilla に関する食えない事情は BugzillaBugzilla-jp にでも任せておくことにして、 ここでは Mozilla に関するあまり知られていない( と言うか、知られていなそうな ) Tip を 紹介することにしました

対象とする Tip は基本的には JavaScript を中心としますが、 CSS や HTML に関するものもありますし、Mozilla のバージョンによっては 動かないものがあったり廃棄されたものがあるかもしれませんので怒らないでくださいね〜 f(^^;

スタイルシートを切り替える

「デザイン的にはこのフォントサイズだけど大きなフォントでも見せたい」とか 「画面サイズや比率に応じてレイアウトを変えたい」とか スタイルシートを切り替えたいことがあります

そこで HTML4.01 の仕様を見ると このような要求は「代替えスタイルシート」でできることがわかります

<link rel="alternate stylesheet" href="style2.css" type="text/css">
<link rel="stylesheet" href="style1.css" type="text/css">

しかし、この仕様はスタイルをフォントサイズのスタイルシート群と配色のスタイルシート群 などの複数のグループに分類できないようなので、 やはり代替えの位置づけでしかないように思えます。
また、代替えスタイルシートをブラウザから選択できる機能は現在のところ Opera 及び Mozilla系のブラウザしかないようです

切り替えるスタイルシートをグループ分けしたり、IE でも適用できるようにするには Style オブジェクト の disabled プロパティを JavaScript で制御すれば比較的簡単に実現できます

<style type="text/css" id="style2"><!--
    :
スタイルの定義
    :
--</style>
<style type="text/css" id="style1"><!--
    :
style2 のスタイルの再定義( 別セット )
    :
--</style>
<script type="text/javascript"><!--
// style1 の disabled を設定する関数
function chgStyle1(n){
  var element=document.getElementById('style1');
  if(element) element.disabled=n;
  return false;
}
// --></style>
<body>
    :
<script type="text/javascript"><!--
// スタイルを切り替えられるブラウザのみメニューを出す
if(document.getElementById){
  document.write(
     '<a href="javascript:void(0);" '
    +'onclick="return chgStyle1(true);">'
    +'スタイル1<\/a>'
    +'<a href="javascript:void(0);" '
    +'onclick="return chgStyle1(false);">'
    +'スタイル2<\/a>'
    );
}
// --></style>

簡単なサンプルはこちら

* もちろん style要素でなく link要素でも同じように切り替えることができます。
また、disabled プロパティは Mozilla の DOM の HTMLStyleElement にありますが、 HTML4.01 の仕様に載っていないせいか

<style type="text/css" disabled>

などとしても IE6 は言うことを聞いてくれますが Mozilla では効果ありません(笑)

適用されているスタイルを取り出す

HTML要素に対応するオブジェクトの style プロパティは inline style ( タグの style属性として記述したスタイル )の内容を表すので、 スタイルシート( styleタグ要素 )に記述した内容は設定されません。

ある要素に適用されているスタイルを取り出すには document.defaultView オブジェクトを使用して取り出します。

// 'element' 要素の background-color の値を読み出す場合
var element=document.getElementById('element');
var style=document.defaultView.getComputedStyle(element,null);
// 'first-line' 疑似要素なら
var style=document.defaultView.getComputedStyle(element,':first-line');
var bgcolor=style.getPropertyValue('background-color');

実際に試してみたい方はこちら

この動作は IE の style.currentStyle に似ていますが、 サンプルの挙動を見ればわかるように currentStyle とは多少異なります

* getComputedStyle に似たメソッドとして getOverrideStyle があります
これは W3C DOM2 の仕様を見ると、どうやら IE の runtimeStyle に似ている ( またしても ^^; )ようですが Mozilla(1.2b) の IDL には 実装してあるように見えても、実際に探してみるとメソッドが見つかりません(笑)

まず、気が付くことは color は rgb(red,gree,blue) の形であり、 font-size は単位が px 固定のようです ( 色々な単位系で指定された場合にどれかに統一する必要があったのかもしれません )

次に、currentStyle では疑似要素に対するスタイルは取得することができません ( まぁ、IE が getComputedStyle をサポートすれば済む話ですが... )

その他には現在の Mozilla(1.2b) では全てのプロパティが 必ず設定されているわけではないようなので実際に使用する場合は 事前に確認した方が良いようです

また、ちょっと気が付きませんが疑似要素のスタイルには疑似要素でないスタイルとして 設定した内容が反映されないようです

p{ background-color:#f8eeff; font-family:Arial; }
p:first-line{ font-weight:bold; }
div{ font-family:sans-serif; }

などとして 'p:first-line' 要素の background-color プロパティを取得しても #f8eeff にはならずに transparent になります

* CSS2 の仕様には疑似要素の位置づけは暗黙の '<p:psuedo-element>' タグの追加 としているようなので、そのまま作るとこんな動作になるのかもしれません ( 期待値とは違いますけどね f(^^; )

また、font-family に関しては 総称ファミリとファミリ名を別に扱っているようです
例えば上の例で p 要素の親が div 要素である場合の p 要素の 'font-family' は 'Arial' ではなく 'Arial,sans-serif' になります

透明度を変える

IE には文字や画像の透明度等を変える機能として Alpha フィルタがあります

この機能は HTML でも CSS でもない IE独特の機能で、 指定方法もちょっとプログラム的です(笑)

Mozilla は W3C の仕様をベースにしていますからフィルタ機能はありません が透明度の変更はサポートしています
この機能は当初(M18頃) 'opacity' プロパティとして実装されましたが CSS2 にはないプロパティなので名称を Mozilla 独自の実装であることがわかるように '-moz-opacity' に変更されました

* Mozilla の実装では、取りうる値はアルファ値で、 W3C CSS3 のTransparency: the 'opacity' property と同様、the range[0.0,1.0] となっています

<div style="-moz-opacity:0.8">Mozilla</div>
<div style="-moz-opacity:0.5">Mozilla</div>
Mozilla
Mozilla
document.getElementById('idName').style.MozOpacity=0.8;
document.getElementById('idName').style.MozOpacity=0.5;

スクリプトでのサンプルはこちら

* 実は、-moz-opacity には百分率での指定があったのですが、 CSS3 の仕様に合わせるためか Mozilla 1.3 の頃から削除されたようです

ボーダ枠の形状を変える

opacity と同様 CSS3 で実装される予定のボーダ枠のコーナの形状の変更も実装されています
但し、CSS3(Working Draft 7 Nov 2002版) Bordersと異なるところは CSS3 が楕円の長軸と短軸の半径を指定するのに対して、Mozilla では円の半径になっています

<div style="-moz-border-radius:25px 0px 0px 25px;">Left</div>
<div style="-moz-border-radius:0px 25px 25px 0px;">Right</div>
<div style="-moz-border-radius:25px 25px 0px 0px;">Center</div>
Left
Right
Center

スクリプトでのサンプルはこちら

矩形のボタンやブロック要素に不満を感じたら、 コッソリと指定してみても良いかも f(^^;

* Opacity の場合は IE ではフィルタで代用することができますが、 この機能は現在(2002年11月)のところ Mozilla のみです
従って、デザインの中心的な場所で使用すると色々と面倒なので FORM要素の submit, reset ボタンなどやボーダ枠で強調する場合などに、 ちょっと使ってみるって手をオススメします
#> CSS3 が REC になったとしても IE が直ぐに対応するわけでもなさそうですし...

アウトライン枠を変える

ボーダ枠はキーボードフォーカス( キー操作対象 )のある要素に表示される、 幅を取らない矩形の描画要素として表現されます

この表示を変更したい場合はそう多くありませんが、全くないわけでもありません

例えば、初期状態での動作では描画されないテキスト入力域のデザインにより テキスト入力域であることが分かりづらいなどの理由でアウトライン枠で強調したい場合です

#chgoutline1:focus { border:       2px dotted #993366; }
#chgoutline2:focus { -moz-outline: 2px dotted #993366; }

* もちろん -moz-outline は Mozilla 専用のプロパティですが、 IE で代替え処理として border で強調したい場合は疑似要素 ':focus' をサポートしていないため スタイルシートのみではできません

JavaScript を使用するなら onfocus, onblur を利用して、 こんな関数を呼び出すことでできそうです

function chgborder(obj,dir){
  if(document.all)
    obj.style.border=dir?
        '2px dotted #993366':'2px solid #ff9966';
}

スクリプトでのサンプルはこちら

* サンプルには -moz-outline-radius がありますが、このプロパティは動作しません

CSS3(Working Draft, 2 Aug 2002版)を見ると このプロパティに該当するプロパティはないので、 一時的に実装した名残か検討中なのかもしれません
#> border-radius があるので、これに合わせても良いと考えますが...f(^^;

テキスト入力の文字を選択する

用途は限られていると思いますが、 テキスト入力( INPUT, TEXTAREA )に表示されている文字列を選択したり、 選択された文字列やカーソルの位置を検出することもできます

選択状態にするには

// テキスト入力の id を 'ta' とすれば
start =  5;  // 6文字目から
end   = 10;  // 10文字目まで
document.getElementById('ta')
        .setSelectionRange(start,end); // 設定

選択状態を取り出すには

// テキスト入力の id を 'ta' とすれば
var element = document.getElementById('ta');
var start = element.selectionStart;  // 開始位置
var end   = element.selectionEnd;    // 終了位置
var selection = element.value.substr(start,end-start); // 選択文字列

サンプルはこちら

* 因みに、テキスト入力以外の選択中文字列は、 今でも document.getSelection() ね (^^

要素を表示領域に移動する

同じページのウィンドウ外に表示されている要素を 見える位置に移動する手段としてアンカー( A )タグを 使用する場合が多いですが、このタグはあくまでもインライン要素を対象としているので ブロック要素を指定することができません

また、その挙動も IE, Moz の場合右上コーナにくるように配置されますので もし既にウィンドウ内に該当の要素が表示されていても表示位置の移動が発生します

このような場合には scrollIntoView を使用します

// 'element' 要素をウィンドウ内に表示するよう移動する場合
var element=document.getElementById('element');
element.scrollIntoView(false);
// 'element' をウィンドウ内の左上コーナ( できれば )に表示する場合
element.scrollIntoView(true);

サンプルはこちら

* scrollIntoView メソッドは W3C DOM では規定されていない関数で、 IE と同じ呼び出し形式のものです

IE との違いは IE がページ内のアンカーにジャンプするのと同じ挙動であるのに対し、 パラメータに false を指定した場合 Mozilla ではページ内に該当要素が 表示されている場合は移動しませんし、 右方向は上方向への移動時と同じ挙動( つまり左端に要素がこない )です

表示領域をページのサイズに変更する

時々コンテンツのレイアウトに合わせて、ウィンドウサイズを調整したい場合があります

通常はレイアウトをある程度厳密に設計し、 そのレイアウトが表示できるサイズのウィンドウを開くと思います
( JavaScript的な解決方法は右下にアンカーとなる見えない要素を配置して onLoad イベント時にリサイズする手法でしょうか (^^; )

しかし、このような手法ではブラウザ依存の要素( ウィンドウ枠や制御できないマージン幅など ) があるため、ある程度の余裕を含むサイズを指定する必要があります

もし、キッチリしたサイズにウィンドウをリサイズしたいなら、 sizeToContent メソッドを使用します

window.sizeToContent(); // 単に呼び出すだけ(笑)

サンプルはこちら

* 実はこのメソッド、位置やサイズが動的に変わる要素があるなどの場合には スクロールバーが表示されてしまうことがあります

レンダリング時の演算の問題のような気もしますが、
とーぶん直りそうにもないカンジ f(^^;

JSファイルの文字コードを指定する

スクリプトで繰り返し使用する部分を汎用化して、外部JSファイルとして使い回すことはよくあることです

この JSファイル に日本語を含めたために、 いろいろなトラブルに見舞われた経験のある人も多いのではないでしょうか

これは、ブラウザが外部ファイルに期待する文字コードと実際の文字コードが異なるために スクリプトの評価に失敗することに起因します

* 時には JSファイルのコメントに日本語を使用したことが原因でエラーになったりもします

このような問題に対する対処は、「SCRIPT タグに charset を指定する」です f(^^;

<script src="jsfile.js" charset="EUC-JP"></script>

* 実は、この方法は W3C HTML4.01 の The SCRIPT element で規定されています
この属性の指定を受け入れる他のブラウザを調べてみると以下のようになります

Browser結果備考
IEWin版は 6以上、Mac版は 5以上
NN4 以上
OperaWin版 7.03 (*1)その他は不明
Konquerorバグあり(*2)

*1 動作を見ると charset 指定が有効なのではなく、 文字コード自動判別が読み込むファイル毎に効いているためのようにも見えます

*2 Konqueror は KDE2.2.2 のもので確認したのですが、 HTML側が UTF-8 の場合にバグ( フォント? )がありうまく表示されませんでした
また、3.1.2 の場合は charset 指定は無効でした f(^^;

サンプルはこちら

スクリプトソースを切り替える

外部JSファイル と CGI を組み合わせたページを作成する場合など、 状況により JSファイルを再度読み直したり切り替えたいときがあります
このようなときにはどうすればよいのでしょうか

すぐに試してみる方法は script タグの src 属性を変更することでしょうか?

<script id="db" type=text/javascript" src="db.js"></script>
    :
document.getElementById('db').src='db.js';

残念ながら、この方法は Mozilla では動作しません

* IE なら動作します

この理由は、Mozilla ではインラインを含むスクリプトの評価はドキュメント構築時に 一度だけ行われるためで、 再評価させたい場合は全ての子と属性を予め指定してからドキュメントに追加する必要があります

// script タグを新規に作る
var new_node = document.createElement('script');
new_node.src    = url;
new_node.id     = id;
new_node.onload = on_load;

// document に組み込む
var cur_node = document.getElementById('db');
cur_node.parentNode.replaceChild(new_node,cur_node);

また script タグは、読み込んだデータや関数が利用可能になったことを通知させるために onload イベントが使用できます

* このスクリプトは IE6 でも動作しますが、 onload イベントはサポートしていないようです
従って、クロスで使用する場合はスクリプト側に仕掛けが必要になります

* IE の script タグの onload イベントは MSDN によれば 4.0 よりのサポートとなっていますが、 有効なのは HTML上のタグとして記述した場合のみのようです (-_-;

コンテキストメニューを作る

ブラウザの右クリックで表示されるメニュー( コンテキストメニュー )は よく使う項目のショートカットメニューとして重宝しますが、 時として自作のメニューを表示したい場合があります

このメニューはブラウザのメニューなので、 現在の W3C のドキュメントには定義されていません

ですが、Mozilla ではこのメニューを表示するイベントは IE と同様 oncontextmenu で捉えることができます

// タグの属性で指定する場合
<div id="pane" oncontextmenu="return popupMenu(event);">
自作のコンテキストメニュー表示領域
</div>
// JavaScript で指定する場合
document.getElementById('pane')
    .addEventListener('contextmenu',popupMenu,true);

* addEventListener で登録したハンドラを取り消すには removeEventListener を使用しますが、 この関数は Mozilla のバージョンに依っては正しく動作しないようです

登録・取り消し操作を行うスクリプトではオブジェクトの 'oncontextmenu' プロパティで 登録・取り消し操作をした方が良いかもしれません

また、クリックされた時の情報は通常のマウスイベントと同様、 currentTarget, pageX, pageY 等で知ることができますから もし、表示するならイベントの上位への伝達を抑止して 自作メニューを表示すれば良いでしょう

myMenu = null;         // メニューオブジェクト
// oncontextmenu イベントハンドラ
function popupMenu(e){
  e.cancelBubble=true; // 上位へイベントを伝えない
  hideMyMenu();        // 表示中のメニューを一旦消す
  // メニューの位置を設定して表示
  myMenu = document.getElementById('pane');
  myMenu.style.left = e.pageX+'px';
  myMenu.style.top  = e.pageY+'px';
  myMenu.style.display = 'block';
  return false;
}
// メニュー消去関数
// ( body要素の onclick などで呼び出す関数 )
function hideMyMenu(){
  if(myMenu){
    myMenu.style.display = 'none';
    myMenu = null;
  }
}

サンプルはこちら

* よく、HTMLのソースを見られないようにする目的のためにこのイベントを無効化する人がいますが、 操作性を悪くするだけの役にしか立ちませんので注意しましょう f(^^;

モーダルウィンドウをポップアップする

JavaScript でウィンドウを表示する際、 位置やサイズだけではなくウィンドウスタック( ウィンドウの重なり )や ウィンドウフォーカスの制御( modal/modeless )をしたい場合があります

このような場合、IE なら showModalDialog/showModelessDialog 関数を使いますが Mozilla では単に window.open メソッドで同様の効果を得られます

// modal の場合
features="width=300,height=200,modal";
// modeless で常に親ウィンドウの前面にする場合
features="width=300,height=200,dependent";
window.open(url,win_name,features);

* 実は dependent 指定は NN4 からあります

スクリプトでのサンプルはこちら

* modal, dependent の他に指定できるあまり知られていないオプションには以下のものがあります

dialog
dependent に似ていますが最大化・最小化ボタンが表示されません
# ウィンドウメニューには表示されたりするのは愛嬌かも(笑)
# また、ESCキーを操作してもウィンドウは閉じないようです f(^^;
minimizable
dialog と合わせて使用するとまるで dependent 指定(笑)

* この他には centerscreen とか all とかありますが Mozilla 1.1 レベルでは 動作しないようです

サイドバーにページを登録する

サイドバーは「天気予報」や「ニュース」などちょっとしたミニ情報を表示したい場合便利な機能ですが、 パネルを自作して登録することができます

// パネルのタイトル
sbarTitle     = 'Mozilla DOM Samples';
// パネルのURL
sbarURL       = 'http://cgi.din.or.jp/~hagi3/Mozilla/SampleList.cgi';
// パネルのカスタマイズ用ページの URL
sbarCustomURL = '';

// パネル登録関数
function addMyPanel(){
  if(window.sidebar && window.sidebar.addPanel){
    window.sidebar.addPanel(sbarTitle,sbarURL,sbarCustomURL);
  }
}

* addPanel メソッドの使用に関しての注意を記しておきます

addPanel の存在性チェック
例では関数内で window.sidebar, window.sidebar.addPanel をチェックしていますが 実際には addMyPanel 関数を呼び出すボタンやリンクの表示を抑止した方が親切でしょう
表示するパネルのURL( sbarURL )の指定
指定する URL は絶対表記( http://... )でなければなりません
カスタマイズ用 URL
addPanel の第3引数はサイドバーに表示するパネルのカスタマイズ用ページの URL で、 指定しておくとサイドバーのカスタマイズダイアログの「タブをカスタマイズ」 ( Customize Tab... )で呼び出すことができるようになります
用意しない場合は '' を指定します

window.sidebar オブジェクトには addPanel メソッドの他に addPersistentPanel( 常駐型パネルの登録 ) や addSearchEngine( 検索エンジンの登録 ) などのメソッドがあります

* 実はこれらのメソッドは JavaScript で記述されていて、 Windows なら bin\components、 Linux なら /usr/lib/mozilla/components にある nsSidebar.js で定義されています

興味があるならこのファイルを覗いてみると良いでしょう