本記事でのスクリプトを実際に利用したサンプルは、以下で公開しております。
CSSで実現するポップアップメニューでは、CSSだけでポップアップメニューが実現出来る事を実例を交えて解説いたしました。
しかし、現在まだユーザ数が多いインターネットエクスプローラ 6.0では、CSSだけでポップアップメニューを実現する事は出来ません。
このため、インターネットエクスプローラ 6.0に対しては、ポップアップしないままにしておくか、JAVAスクリプトなどの別の方法で対応するかのどちらかと言う事になります。
ここでは、JAVAスクリプトを併用する方法について解説いたします。
尚、前提条件として、CSSで実現するポップアップメニューで解説しているHTMLのマークアップ方法とCSSを用いるものとして話を進めていきます。
試しに、PC環境の
などでご覧の方は、以下の実験サイトにアクセスしてみてください。
それでは、実際にスクリプトを作ってみましょう。
インターネットエクスプローラ 6.0でポップアップメニューを実現するスクリプトのコードは以下のようになります。
/*
インターネットエクスプローラ 6.0まででポップアップメニューを実現するためのスクリプト。
*/
menu_ID='MENU_NAVI'; // メニューバーに与えたID。
pm_onload=window.onload;
// IE 6.0であれば、スタイル調整をする。
if (document.all && !window.opera &&
navigator.userAgent.indexOf('Trident/')<0 &&
navigator.userAgent.indexOf('MSIE 7.')<0) {
window.onload=style_IE6;
}
/***************************************************************/
function style_IE6() {
/* onloadで実行させるべき処理があれば先にやっておく。 */
if (pm_onload) pm_onload();
/* メニューバーがなければ何もしない。 */
if (!(ele=document.all[menu_ID])) return;
/* メニューバーの幅を100%にする。 */
var i=document.documentElement.clientWidth || document.body.clientWidth;
ele.style.width=i+'px';
ele.style.height='1.7em';
/* メニューバーからカーソルが消えた場合にポップアップメニューを消すようにする。 */
ele.style.display='block';
ele.onmouseout=hide4IEall;
/********************************************************
<p>要素(ポップアップメニューへの見出し)に
1.カーソルが置かれた場合に下位のポップアップメニューを表示する、
措置を執る。
********************************************************/
var ele2=ele.getElementsByTagName('p');
i=-1;
while (++i<ele2.length) {
ele2[i].onmouseover=show4IE1;
}
/*
<ul>要素(ポップアップメニュー)に
1.カーソルが置かれた場合に自分自身が消えないようにする、
2.置かれたカーソルが去った場合に消すようにする
措置を執る。
*/
ele2=ele.getElementsByTagName('ul');
i=-1;
while (++i<ele2.length) {
ele2[i].onmouseover=show4IE2;
ele2[i].onmouseout=hide4IE2;
}
}
var timeID;
var m_obj='';
/*********************************************************
ポップアップメニューを全部消す処理。
*********************************************************/
function hide4IEall() {
clearTimeout(timeID);
/*
すぐには消さず、0.5秒経つまで消さない。
※こうしないと、他の表示させるべき箇所にカーソルが移動しても消されてしまうため、
*/
timeID=setTimeout('hide4IEall_2()', 500);
}
/* ポップアップメニュー全消し処理本体。 */
function hide4IEall_2() {
clearTimeout(timeID);
var ele=document.all[menu_ID];
if (!ele) return;
ele=ele.getElementsByTagName('ul');
i=ele.length;
while (--i>=0) {
ele[i].style.display='none';
}
}
/*********************************************************
指定されたポップアップメニューを表示させる処理。
*********************************************************/
function show4IE1() {
hide4IEall_2(); //事前に全部ポップアップメニューを消す。
// <p>要素と兄弟要素となっている<ul>要素を探す。
var ele=this.parentNode; //一旦親要素ノードの…
ele=ele.childNodes; //子ノード集合を得、その中から探す。
var i=ele.length;
while (--i>=0) {
if (ele[i].nodeType!=1) continue;
if (ele[i].tagName.toLowerCase()=='ul') break;
}
if (i<0) return; //見付からなかった場合。
// 見付かったらそれを表示させる。
ele[i].style.display='block';
}
/*********************************************************
カーソルが置かれたポップアップメニュー自身のを表示処理。
*********************************************************/
function show4IE2() {
clearTimeout(timeID); //ポップアップメニュー消去処理が行われた場合はキャンセルする。
this.style.display='block';
}
/*********************************************************
カーソルが置かれたポップアップメニューから
カーソルが外れた場合に自分自身を消去する処理。
*********************************************************/
function hide4IE2() {
clearTimeout(timeID);
m_obj=this;
/*
すぐには消さず、0.5秒経つまで消さない。
※こうしないと、他の表示させるべき箇所にカーソルが移動しても消されてしまうため、
*/
timeID=setTimeout('hide4IE2_2()', 500);
}
function hide4IE2_2() {
clearTimeout(timeID);
m_obj.style.display='none';
}
ここでは重要と思われる点を中心に解説して行きましょう。
以下、インターネットエクスプローラ 6.0でポップアップメニューを実現するスクリプトの具体的な処理について簡単に解説いたします。
スクリプトの冒頭では、
MENU_NAVI)を指定しておき、style_IE6()を呼ぶようにしております。
インターネットエクスプローラ 6.0以前であると判定されるのは、以下の条件を全て満たした場合です。
document.all オブジェクトが存在している事document.all オブジェクトはインターネットエクスプローラの独自実装です。window.opera オブジェクトが存在していない事オペラでも、インターネットエクスプローラとの互換性を確保するため、document.all オブジェクトを実装しております。
また、オペラでは、オペラである事を識別出来るようにするため、window.opera オブジェクトを独自に実装しております。
従って、window.opera オブジェクトがあればそれはオペラなので対象外と言う事になります。
MSIE 7. や 同 8.0以降(8.0での7.0互換モードを含む) Trident/ が入っていない事が条件です。style_IE6() の処理。函数 style_IE6()は、インターネットエクスプローラ 6.0 以前で呼び出される函数です。
style_IE6() での事前処理。函数 style_IE6()では、先ず事前処理として、以下の処理が行われます。
style_IE6() での本処理。函数 style_IE6()で事前処理を済ませたら、いよいよ本処理に入ります。
本処理で行っている事は以下の三つです。
hide4IEall()を呼ぶように仕掛ける。show4IE1()を呼ぶように仕掛ける。ポップアップメニュー内にあるメニュー(<ul>要素)に於いて、
show4IE2()を呼ぶようにhide4IE2()を呼ぶようにそれぞれします。
ポップアップメニューとなる要素から、<p>要素或いは<ul>要素だけを抽出するのは 要素オブジェクト.getElementsByTagName() メソッドで造作なく行えます。
hide4IEall() の処理。函数 hide4IEall()は、全てのポップアップメニューを消す函数です。
実際には本体は別の函数である、hide4IEall_2()であり、函数 hide4IEall()は 0.5秒後にこれを呼び出すように設定しております。
何故すぐに消去処理をしないのかと申しますと、この函数はマウスカーソルがポップアップメニューのメニューバー部分から外れたときに呼び出されるからです。
メニューバーから外れたカーソルは何処に行くか…表示中だったポップアップメニュー部分にカーソルが移動した場合、この函数で既に消されてしまってはポップアップメニューとして使い物になりません。
このため、0.5秒と言う短いタイムラグを発生させてその間にポップアップメニューを表示させるべき箇所にカーソルが移動していたら、この函数で予定した全消去処理をキャンセルさせる、すなわちポップアップメニューの全部消去を行わないようにします。
函数 hide4IEall_2()で行われる全部消去の処理は、指定されたIDからメニュー部分となる<ul>要素を抽出し、それらを全て非表示にすると言うものです。
show4IE1() の処理。函数 show4IE1()は、見出しをポイントした際に対応するメニューを表示させる函数です。
初めに、
が呼び出されていて、0.5秒以内にこれらの本処理が発動するようになっているのであれば、それをキャンセルしてメニュー消去を防止します。
その上で、当該要素の親要素内にある <ul>要素をスキャンして、見付かればそれをブロック表示にするようにします。
show4IE2() の処理。函数 show4IE1()は、ポップアップメニューがポイントされている際に、それが消えないようにするための函数です。
具体的には函数 show4IE1()同様、
が呼び出されていて、0.5秒以内にこれらの本処理が発動するようになっているのであれば、それをキャンセルしてメニュー消去を防止します。
hide4IE2() の処理。函数 hideIE2()は、見出しをポイントした際に対応するメニューを表示させる処理です。
具体的には函数 hide4IEall()同様、本処理を函数 hide4IE2_2()に分離し、0.5秒経過してから消すようにします。
このようにした理由も全く同じです。
このスクリプトは実は ○○.all[△△] を ○○.getElementById(△△) に書き換えれば、ファイヤーフォックスやサファリなどでも実行可能になります。
.all[△△] をサポートしているので、オペラで動作させるのであれば書換えは不要です。ただ、CSSのみでやれればその方が遙かに簡単なので、どうしてもCSSだけでは実現出来ないインターネットエクスプローラ 6.0までのみを対象としております。
勿論、ポップアップの際に動きを持たせたいなどと言うような場合には上記のような書き換えを行うなどして他のブラウザでもこのスクリプトを通す必要が出てきます。