ないブログに表示されています。新しい記事を書く事で広告が消えます。[]ソフトメニューを各ページの先頭に表示したい階層メニューが出来たので、、今度は本来の目的であったソフトメニュー(ポップアップメニューとも言うらしい)を表示出来ないかを考えてみた。ソフトメニューは、自分のHPでも各ページに付けているが、BLOCKBLOGでは、自分のHPにつけている物とは、違ったもので実現するしかない。それは、階層メニューでも書いたが、なにしろHTML文が直接書けないので、BLOCKBLOGのHTML文内にある情報を用いて、実現するしかないためである。今までのJavaScript的な作り方は、前もってHTML文に操作する情報を書き込んでおくか、またはタグをdocumenu.writeして、それをJavaScriptを用いて制御するのが基本だったんですね。表示している内容を操作して、何かを表現することなんて考えることも出来ない。カテゴリ一覧をコピーして、もうひとつ同じカテゴリ一覧を別なところに配置することなんて出来ないし、そのカテゴリ一覧をポップアップメニューのようにマウスイベントを用いて制御することは、もちろん出来っこない。DOMではどうなの?これがDOMでは、上記がなんとすべて出来ちゃう。出来るのかというと、JavaScriptと根本的に設計思想が違うんですよね。JavaScriptは既に存在する文書構造の範囲内でしか操作できない。ある情報をいくらでもコピー出来るし、新たに情報も作れるし、もちろん既にある情報の内容を変更することや、削除することも出来ちゃうんですね。このDOMの考え方を用いて、作成したツールは、ほとんど見たことがない。自分もそうだったが、やはりタグをdocument.writeしたりして作成いるし、その中でonclickとかonmouseoverとか書いて、イベントを制御している。今回、document.writeとかは使わず、ほぼ完全にDOM仕様に合わせて作成してみた。書式だけは面倒なので、従来のIE記述で書いた。はじめは、なにしろDOMの関数名(メソッドとか)は、やたら長いし、さらに、タグの要素、その子要素とかを順番に操作したりするので、ソースがかなり長くなるだろうなとも思っていた。ソースも従来のソフトメニューのものより断然短くなった。一度、DOM的なJavaScriptに慣れると、今までのJavaScriptはなんてダサイんだ。思ってしまうところが、DOMの凄いところですね。いうことで、今回のソフトメニュー導入の基本設計を。【考え方】?先頭のタイトル文字および画像領域と、本文の間に隙間を空けて、ここにソフトメニューを埋め込む。?ソフトメニューに表示する内容は、左側のmenuブロック内の各ブロックを表示する。コメント、最新トラックバック等。?まず、ソフトメニューを埋め込むには、本文領域と左側のmenuブロックをソフトメニューの高さだけ下にずらせばよい。これは、これらの領域がbox領域上で管理されているので、このbox領域の書式をposition:absoluteに変更し、そのtop位置を必要分下にずらせばよい。左側のメニューの内容をコピーして、ソフトメニューの位置に配置する。ソフトメニューの親メニュー1個の横サイズは、手を抜いて120px固定とする。?子メニューの表示非表示の制御は階層メニューと同じでdisplay属性を用いればよい。数秒後にまた隠してやればよい。「マウスが載ったよ」と分かるように背景色を違う色に変えてやる。そこからマウスが出たら背景色を元に戻してやる。勉強のつもりでちょっとまとめておこう。DOMは基本的に単純な考え方で作られているんですね。文書を各要素のツリー構造で定義し、このツリー構造の親子関係で制御する。今回ソフトメニューを配置するところの親は、BODYタグである。ここから配置された各種タグが次の子要素である。その子要素の中に定義された要素が、また子要素を構成する。各dt,ddタグが親の文字要素これらを、基本的には以下のメソッド(まあ制御関数みたいなもの)で制御する。これ以外にもメソッドはあるけど、今回の目的には、これらでまあ十分かな。親オブジェクト.appendChile(追加するオブジェクト)オブジェクト=複製元オブジェクト.cloneNode(true)では、具体的に基本となるポイントだけ書いてみる。【menu領域をコピーするには】コピーするmenu領域のDLタグおよび、それ以下にある子要素をすべてcloneNodeで複製し、それをbodyタグにappendChildで追加すればいい。これだけで、コピーできちゃうとは、DOMは簡単ですね。求めた値には、CSSファイルで設定したmarginやpaddingの値がプラスされている。そのため、指定値により、ソフトメニューの高さより大きな隙間が空いてしまう。問題は、CSSで指定してあるmarginやpadding値をどうやって取得するかだが、この取得方法は、出来るのか出来ないのか良く分からなかった。そこで方針を変えて、既にあるDT要素から求めるのではなく、コピーしたDT要素に必要なmargin,padding値を設定してやった後に求めるようにした。コピー後のDT要素のmarginとpaddingをソフトメニューの書式分設定後、そのoffsetHeightを取得してやればよい。【マウスイベントの制御】マウスイベントは先頭の親のDLタグにommouseoverとonmouseoutを登録してやれば、その子要素にはマウスイベントを指定しなくても、マウスイベントが反映される。マウスイベントは、必ずoverとoutが対で来る。イベント発生時には、それぞれのイベントで指定した制御関数内で処理してやればいい。普通は数秒後に消している。数秒経たない内に、別の親メニューにマウスが載れば、その時点で、既に表示済の子メニューを消して、対応する新たな子メニューを表示するようにしなくてはいけない。上左Margin=0pxにして、先に求めたbox領域の左位置へずらす。・メニュー要素と同じものを複製し、idを変える。・複製したメニュー要素をソフトメニュー位置に配置する・Mozzilaの場合は、デフォルトでマージンが設定されるので、マージン=0pxにする。・ソフトメニューの書式設定(同時に各メニュー要素の最大縦サイズを算出)・ソフトメニューの親要素DLにマウスoverイベント、マウスoutイベントを登録する。・リンク要素なら背景色を変える。・親要素のDLタグを求める・メニューの表示制御の判断。・メニューを非表示なら、表示する。・リンク要素なら背景色を元に戻す。・親要素のDLタグを求める・メニュー表示を1.5秒後に非表示にするため、タイマイベントを登録する。・タイマ起動中ならクリア。・対象となるDLタグのメニューが表示中であれば、非表示にする。onLoad関数の登録ということで、出来たが、ここで思いも寄らないことが。【大問題が】なななんと、バックナンバーが画面からはみ出してしまう。バックナンバーは、50個ぐらいあるので、ノートPCだと画面からはみ出してしまう。今の仕様では、画面から下にはみ出すと、マウスだけで操作しようとしても、はみ出した下側を表示させられない。^^);;;まっとうにやろうとすると、年代毎に分けて、そこからカスケードして横に月毎の項目を表示するようにすればいいが、なんか大変そう。手を抜くなら、バックナンバーの表示個数を50個でなく、15個ぐらいに設定してやればいいが、どうしよう。50個では、一番最初の記事が入らなくなるので、もっと表示件数を増やしてやればいいんですね。【BLOCKBLOGの仕様が不足かな?】ということで、思いついたのがBLOCKBLOGさんに月別リストの改善をお願いすることでした。今の仕様では、たぶん皆さん困るときが訪れるはず。上の改善がやってくれるんなら、わざわざカスケード作る必要もないかもね。いうことで、BLOCKBLOGさん次第でどうするかだけど。それ待っていても仕方ないので、お願いしたことと同じようなことを先に実現しちゃいましょう。【考え方】BLOCKBLOGにお願いしたことは、当然出来ないけど。残りはmoreで制御させて表示させてやれば、同じようなことが出来ますね。このmore表示を行うには、以下のメソッドが新しく必要です。document.createElement(作成するタグ名)document.createTextNode(作成する文字列)【注意したところ】1)Operaは、DLリスト内のある範囲のDD項目を表示する際にその項目の範囲での最大サイズで、DD項目の表示サイズを変えている。IE,Mozzilaは、上記のようなことはなく、サイズは変らない。最大表示数より多いものは、非表示のままとする。・more項目のDIVタグのID=上下判定文字+親DLタグのIDとして作成する。・more文字列をDIVタグに追加する。・moreDIVタグを先頭と最後のDDタグに上被せで配置する。・z-index属性を親DLタグのものより+1する。・上側のmoreDIVタグは、非表示にする。下側のmoreDIVタグは、表示する。・moreDIVタグにonclickイベントを登録する。・DDタグ内を調べ、上端表示位置と下端表示位置を求める。・クリックされた上下moreにより、メニュー内の表示範囲を判断して表示する。・対象となるDLタグのメニューが表示中であれば、非表示にする。・DOMは、ブラウザだと、IE5以上、Mozilla、NN6以上でできるようです。SP1、Mozilla1.6とOpera7.23しかないので、これで確認し、この環境のみのことで書いてある。それ以外のバージョンや、他のブラウザはもちろん無視(動くかどうか不明)。SP1しかないので、これ以外のOSは使ったことがないため無視。・マシンも、PCしか持ってないので、Macとかは、もちろん無視。・BLOCKBLOGの文書構造に合わせて作成してあるので、この文書構造以外は当然動かないで、多分エラーになります。以下の環境で動作確認をやってみたら、さすがに動かない。調査の結果、Mac(Safari)とそれ以外Windowsのブラウザの場合の違いはWindows:Aタグからイベントが発生する。Mac:最上位の親ノードと、最下位のテキストノードからイベントが発生する。適切なノード(DLタグ)まで処理できずに途中のノードを対象として、おかしくなっていた。要するに親ノードがnull(親が存在する)まで探し、もしnullなら、そのイベントを無視するように変えた。色を変えているが、これが変らない。^^);;調査の結果:色の変更は、Aタグ前提で処理していたので、Aタグの下に位置するテキストノードを想定していなかった。そのため、テキストノードで色を変えようとしても変えられなかった。修正:テキストノードの場合は、その親がAタグであれば、ノードをひとつ上のAタグに移して処理するようにした。「more」の文字の上にマウスを移すと、マウスが「+」にならず、色も変らない。調査の結果:Windowsは、問題ないが、Macだとdivと#textノードが別々に扱われるみたい。親の状態を判断して、対象ノードであれば、マウス形状、背景色を変更するように変えた。「more」の文字上では、クリックが効かない。調査の結果:DIVの中にテキスト作成したのに、DIV領域とテキスト領域でイベント範囲が異なるのはちょっと違うんではないのでしょうか?テキストノードにイベントは登録できないようなので、これって仕様の解釈が間違ってると思うんだけど?それとも、自分が何かを勘違いしてる?で、Windowsとは、同じにならない。この解決方法は???修正:Macは、これでいいやと、諦めた。主要ブラウザ間で表示が異なる結果を招くことから、ソフトメニューのみをabsoluteにすれば、デザインには左右されずに好きなとこに配置可能である。隙間は、CSSで開ければ済むので融通性もある。いうことで、box領域を下にずらしているところを削除した。CSS設定部分をスタイルシートで定義した書式で表示するように修正した。面倒なので対応してないところが手抜きですが。^^)【でも直ぐ使いたいという気さくな方】ここ見てね。内容理解できて、何が必要で、どうすればいいかを判断できる人ね。サポート、問合せはごめんね。Mayumi][-]最新記事TIN無しでもアメリカで源泉徴収された税金を全額取り戻したい。(03/11)今日はバレンタインディーだが、バンカラに行ってきた。(02/15)いやーー素晴らしいカラオケ居酒屋だった。(06/30)みなさん腹式呼吸が大事と言うが。(06/25)カラオケ喫茶で、カラオケ大会に出ている方がいる。誕生(10/28)はじめたきっかけ(11/11)公開したけどアクセスは50件(12/13)JavaScriptとの出会い(01/10)HPの内容を変える画期的な出会い(01/10)アクセス。