POPSブログ

jQuery HoverMenu/11

169

  Category:  jquery2012/11/18 pops 

前ページ掲載の HoverMenu 10 は大変わかり難いものです。問題が多すぎたし、バグのあった「IE9」にも対応できるようにHTML構造を変えました。単純な構造での制作をしたかったのですが旨く行きませんでした。新構造のものは解説説明などほとんどありません。(IE6非対応)

 

jQuery HoverMenu 11

文字の読み易さに重点を置き「角丸陰影処理」及び、メニュー要素「タイトル陰影処理」を標準とします。勿論解除を可能です。但し「IE9」に対応するために構造をかえましたから汎用性に欠けます。背景画像をアニメする利点を生かしきれません。
要素上部にボーダーをつけた場合にメニュー要素が少々伸びるのも補正しました。IE7.8で陰影処理をした場合にアニメがぐらつくのも修正可能です。
「角丸陰影処理」「タイトル陰影処理」を別々のDIV要素で構成して、hidden の場所をかえ「IE9」バグが出ないようにしているだけですが、往々にして「IE様」には困ったものです。


li リストの中に配置の例 (サブメニュー付き)、サンプル12


下のサンプルを「HOVER」ください。メニュー背景を移動変化させます。(IE6非対応)

jquery.backgroundpos.js v1.1.0、jquery-1.6.4.js、を使用。

原則、CSS3の装飾の有効な、IE9 Safari Firefox Chrome Opera、対応です。当然「IE7.8」は角丸無しです。

1. 高さ60 CSS3角丸 Shadow処理、固定幅、中央表示、(hover-menu12.js)



ベース背景色の切替 :                   / ベース背景画像 : N A X

要素背景画像の切替 :        

要素背景色の切替(クリア) : 指定色1 指定色2 指定色3 指定色4 指定色5 指定色6 複数色1 複数色2

サブメニュー背景色切替 : 白色 灰色 黒色 / 透明度 : 透明度0.5 透明度1

アクティブ背景色の切替 :                 / アクティブ文字 :        

タイトル陰影の切替 : SHADOW 有り SHADOW 無し (初期はSHADOW有り)

タイトル色の切替 :                      

アクティブ位置の切替 : ホーム 会社案内 サービス お問い合わせ サイトマップ

要素背景色の切替(クリア)は、アクティブ背景色/アクティブ文字色、及び、タイトル色、もクリアされます。タイトル hover は初期のみ機能。


原則、CSS3の装飾の有効な、(IE9) Safari Firefox Chrome Opera、対応です。「IE7.8」は角丸無しです。
IE10 は正常に表示されるものとおもいます。但し未確認です。


HTML JS CSS について


IE9で「親要素」が CSS3角丸陰影処理、overflow:hidden (角丸だけの場合、陰影だけの場合と条件によっても違いあり)で「子要素」の文字に IE独自の shadowフィルターを施すとフィルターが壊れる。情報は見つけられないがおそらくバグでしょう。影響の出ない様に構造を変えるほかに方法は無いようだ。(IE独自のフィルターは以前より問題が有りすぎですが)

説明図


HTML CSSは前のページ及び前々のページのJSに改良をして、IE9でも問題なく動作するようにしたものです。


1.「IE9」でも、角丸陰影処理(CSS3)及び、メニュー要素タイトル陰影処理(IEはfilter)を標準とします。
2. タイトル陰影処理をしない場合は、ベースの色、タイトルの色の選定が非常に難しくなりますから重要です。(文字の見易さを考慮すれば陰影は必要です)
3. 問題になるものではありませんが、上部にボーダーをつけた場合に多少アニメ時にぐらつきがあったものを、修正しました。「IE78」の陰影処理時アニメのぐらつきを防ぐ方法も記載します。
4. サンプルは、簡単なシミュレーション風に仕上げていますので状況がわかるとおもいます。
5. 初期設定で、簡単にデザイン(主に色)変更なるようにしました。(JS参照)


● HTML

次ぎのような構造を作る。IE9バグ対処のために、li構造の中に2つの「DIVボックス」が入り、その1つにサブメニューが入る。標準的な単純構造ではないので汎用性は無くなる。(必ず規定の構造を作らなければ作動しない)


<div id="hover-menu">
	<ul>
	<li class="main-menu active">
		<div class="menu-back">
		</div>
		<div class="menu-top"><a href="リンクURL"><h3>リンク名</h3><br /><p>文字</p></a></div>
	</li>
	<li class="main-menu">
		<div class="menu-back">
			<ul class="sub-menu">
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			</ul>
		</div>
		<div class="menu-top"><a href="リンクURL"><h3>リンク名</h3><br /><p>文字</p></a></div>
	</li>
	<li class="main-menu">
		<div class="menu-back">
			<ul class="sub-menu">
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			<li><a href="リンクURL">サブリンク名</a></li>
			</ul>
		</div>
		<div class="menu-top"><a href="リンクURL"><h3>リンク名</h3><br /><p>文字</p></a></div>
	</li>
	<li class="main-menu">
		<div class="menu-back">
		</div>
		<div class="menu-top"><a href="リンクURL"><h3>リンク名</h3><br /><p>文字</p></a></div>
	</li>
	<li class="main-menu">
		<div class="menu-back">
		</div>
		<div class="menu-top"><a href="リンクURL"><h3>リンク名</h3><br /><p>文字</p></a></div>
	</li>
	</ul>
</div>

IE9のバグが及ばないように、角丸処理(hiddenがなければならない階層)とフィルターを独立したDIVで実行するようにしたものです。IE9には「困り者」です。


● メニュー要素、サブメニュー

メニュー要素は増やせます。サブメニューは必要な場所に挿入します。ともにクラスなどは確実に記入ください。


サブメニューは有れば表示します
<div class="menu-back">
サブメニューのUL LI構造を挿入する、幅がありませんので名前は簡潔に
</div>

注意、事前にjquery.jsの読み込みのあとで、プラグイン jquery.backgroundpos.js を読み込んでおく必要があります。
JS名、ID名、クラス名、activeクラス、などを変更の場合は、JS、CSSの該当の箇所を修正の必要があります。


● JS 標準 (上のサンプルの動作と同じもの、IE6では動作しません)

hover-menu12.js、(簡易記述です、読み込んだら実行します)

アニメ部分の設定が jquery.backgroundpos.js 用です。


//hover-menu12.js
//日本語
//プラグインjquery.backgroundpos.js 1.1.0を使用
//構造をかえてIE9対応に書き換え

(function($){

	$(function(){

		//背景画像中央合わせの x値=(アイテム幅-画像幅)/2
		//現在の計算値、x=(200-110)/2=-45

		//menu要素の高さ
		var menu_H=60;
		//ボーダー使用の場合の幅、使用しないときは0
		var border_H=2;
		//sub-menuの配置位置position-y/CSSとあわせる
		var sub_pos_X=50;
		//サブメニュー下のスペース 5-10
		var bottom_sps=10;

		//中央揃えの幅を取得して自動で幅などのCSSを決める(IE8以上)
		//IE67対応ならCSSの修正が必要
		var center_set="set";//set none

		//複数色データを使用して着色する use 使用しない場合はCSS変更
		var colordata_use="";//use none

		//activeの場合の要素の背景色の使用
		var actcolor_use="use";//use none

		//activeの場合の要素の文字色の使用
		var acttxcolor_use="use";//use none

		//activeの場合の要素上部にボーダーを表示する use
		var actborder_use="use";//use none

		//sub-menuのある場所に矢印を挿入する
		var tiarrow_use="use";//use none

		//背景画像のポジションの変更、又は別画像を配置
		//none及び設定なし=何もしない、chg=位置変更、arrow=別画像配置
		var backpos_chg="none";//none chg arrow

		//色データ
		var active_color="#00CED1";//activeの場合の要素の背景色darkturquise
		var active_txcolor="#FFFFFF";//activeの場合の要素の文字色
		var active_bordercolor="#FFFFFF";//activeの場合のボーダー色、ベースの色に注意

		//複数色データ
		var colordata=["#DB7093","#F4A460","#BC8F8F","#FF69B4","#778899","#00CED1","#9370DB","#6496ED","#CCCCCC",'#EEEEEE'];

		//--------------------------------------------------

		var item=[];
		var subitem_H=[];
		var activeflag=0;
		var menu_base=$("#hover-menu");

		//ul要素の幅を決定して設定を実行する
		if (center_set == 'set') {
			var ul_W=menu_base.children("ul").width();
			menu_base.children("ul").css({'float':'none'});//追加
			menu_base.css({'text-align':'center'});
			menu_base.children("ul").css({'width':ul_W,'margin':'0 auto'});
		}

		//色データで背景着色などの処理
		$(".main-menu").each(function(i){

			item[i]=$(this);

			//要素を個別に複数色に着色
			if (colordata_use == 'use') {
				item[i].find('.menu-back').css({'background-color':colordata[i]});
			}

			//高さの取得/無ければnull
			subitem_H[i]=item[i].find('.sub-menu').height();

			//sub-menuのある場所に矢印を挿入する
			if (tiarrow_use == 'use') {
				if (item[i].find('ul').hasClass('sub-menu')) {
					var ti_elm=item[i].find('h3');
					ti_elm.text(ti_elm.text() + ' ▼');
				}
			}

			//activeの処理、activeクラスがあるか
			if (item[i].hasClass('active')) {

				//activeの位置番号取得
				activeflag=i;

				//active 背景着色
				if(actcolor_use == 'use') {
					item[i].find('.menu-back').css({'background-color':active_color});
				}

				//サブメニューが無い場合、高さがnull
				if (!subitem_H[i]) {

					//active 背景画像ポジションの変更
					if(backpos_chg == 'chg') {
						//位置をCSSで修正
						item[i].find('.menu-back').css({'background-position':'-45px -80px'});
					}
					//active-arrowクラスを与える/CSSを変更する
					if(backpos_chg == 'arrow') {
						//CSSでactive-arrowクラスで処理する
						item[i].find('.menu-back').addClass("active-arrow");
					}

				}

				//active 文字の色を変える
				if (acttxcolor_use == 'use') {
					item[i].find('h3').css({'color':active_txcolor});
				}

				//active ボーダーを設定/高さボーダー分修正
				if (actborder_use == 'use') {
					item[i].find('.menu-back').css({'height':menu_H-border_H,'border-top':'' + border_H + 'px ' + active_bordercolor + ' solid'});
				}

			}

			//サブメニュー一旦けす
			item[i].find('.sub-menu').css({'display':'none'});

			//hover-action
			item[i].hover(
				//over
				function() {

					//activeでサブメニューが無い、何もしないで戻る
					if (item[i].hasClass('active') && !subitem_H[i]) {return}

					//一旦消す
					item[i].find('.sub-menu').css({'display':'block'});

					//処理
					item[i].addClass("hovered");

					//伸ばす高さを計算
					var h=0;//初期値0
					if (subitem_H[i]) {h=subitem_H[i]+(sub_pos_X-menu_H)+bottom_sps;}

					//プラグインアニメ実行
					item[i].find('.sub-menu').css({'display':'block'});
					item[i].find('.menu-back').animate({backgroundPosition:'-45px -60px','height':menu_H+h},600,function (){
						//
					});
				},
				//out
				function() {

					//activeでサブメニューが無い、何もしないで戻る
					if (item[i].hasClass('active') && !subitem_H[i]) {return}

					//処理
					item[i].removeClass("hovered");

					//activeの位置によりボーダーの誤差を修正
					var h2=menu_H;
					//activeの位置番号取得
					if (item[i].hasClass('active')) {activeflag=i;h2=menu_H-border_H;}

					//sub-menuがあれば
					if (subitem_H[i]) {

						//アイテム高さを戻す
						item[i].find('.menu-back').animate({'height':h2},300,function (){

							//sub-menu消す
							item[i].find('.sub-menu').css({'display':'none'});
							//プラグインアニメ実行
							item[i].find('.menu-back').animate({backgroundPosition:'-45px 0px'},400);

						});

					} else {
						//sub-menuが無ければ
						//プラグインアニメ実行
						item[i].find('.menu-back').animate({backgroundPosition:'-45px 0px'},400,function (){
							//
						});

					}

				}

			);

		});

	});
})(jQuery);


● CSS

hover-menu12.css


/* hover-menu12.css 動作簡略形、日本語 */

/* 収納ブロック */
#hover-menu {
display:block;
width:640px;
height:60px;
background-color:transparent;
}

/* 幅を取得のためinline-blockにしている */
#hover-menu ul {
list-style:none;
display:inline-block;
width:auto;
height:60px;
padding:0;
margin:0;
/float:left;/* IE7 */
}
#hover-menu ul li {
list-style:none;
position:relative;
display:inline-block;
width:110px;
height:60px;
margin:0 2px;
padding:0;
text-align:center;
float:left;
/*overflow:hidden;*/
}

#hover-menu ul li a {
text-decoration:none;
margin:0
padding:0;
}

#hover-menu .main-menu {
background-color:transparent;
}

/* 背景画像BOX */
#hover-menu .main-menu .menu-back {
position:absolute;
top:0;left:0;
width:110px;
height:60px;
background:url('/main/images/block_alpha8h.png') no-repeat;
background-color:#EEEEEE;
background-position:-45px 0px;
float:left;
}

/* active-arrowクラス IEルートをきっちり書くこと*/
#hover-menu .main-menu div.active-arrow {
background-image:url('/main/images/arrow_8b.png');
background-position:center bottom;
}

/* IE78 filter陰影 */
#hover-menu ul li .menu-back{
filter:progid:DXImageTransform.Microsoft.Shadow(color=#555555,direction=135,strength=3,enabled=true);
}

/* CSS3角丸陰影 */
#hover-menu .menu-back {
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
box-shadow: 0 0 6px #333;
-moz-box-shadow: 0 0 8px #333;
-webkit-box-shadow: 0 0 8px #333;
}

/* タイトルBOX */
#hover-menu .menu-top {
position:absolute;
top:0;left:0;
width:110px;
height:60px;
float:left;
}
#hover-menu .menu-top h3 {
width:auto;
height:20px;
margin-top:10px;
padding:0 5px;
line-height:20px;
font-size:12px;
font-weight:bold;
color:#CCCCCC;
text-shadow:1px 1px 4px #000000;
cursor:pointer;/*default*/
}

/* IE8 hack タイトル陰影 */
#hover-menu .menu-top h3{
filter:progid:DXImageTransform.Microsoft.Shadow(color=#555555,direction=135,strength=3,enabled=true)\9;
}

#hover-menu .menu-top p {
margin-top:-20px;
line-height:12px;
font-size:10px;
color:#CCCCCC;
cursor:pointer;/*default*/
}

/* hovered */
#hover-menu .hovered .menu-top h3 {
color:#FFFFFF;
}


/* sub-menu */
/* 幅は広げられないabsolute */
#hover-menu .sub-menu {
position:absolute;
top:50px;left:0;
display:inline-block;
width:110px;
height:auto;
margin:0;
padding:0;
background-color:#FFFFFF;
opacity:0.7;
filter:alpha(opacity=70);/* IE */
}
#hover-menu .sub-menu li {
clear:both;
list-style:none;
display:inline;
width:110px;
height:100%;
margin:0 1px 2px 1px;
padding:0;
line-height:16px;
font-size:11px;
text-align:left;
background-color:transparent;
background-image:none;/* 重要 */
overflow:hidden;
}
#hover-menu .sub-menu li a {
text-decoration:underline;
height:100%;
}
#hover-menu .sub-menu li a:hover {
color:#FF0000;
}

設置する環境によりずれる場合などは修正ください。画像パスは合わせてください。


簡単な説明


説明図


IE9でメニュー要素に角丸陰影を、タイトルにも陰影をつけてバグの出ないようにするのに大騒ぎしているだけなんですが、上記のHTMLのように繁雑な構造です。そのため説明など省くためにJSに設定を加えました。

1. activeの場合のデザインなど図示します、JSの先頭の設定をお読みください。
2. 角丸、陰影、最初の色、大きさなどはCSSで変更ください。複数色に染める場合はJS設定です。
3. アニメの背景画像の変更は、jquery.backgroundpos.js の規定に従ってください。px単位が良い。
4. 標準で「IE7」も中央配置になっています。変更の際は下の説明「中央配置の変更」をお読みください。
5.「IE7.8」でメニュー要素に陰影を付けた場合、HOVERすると少し動きます。そのままで使用できますが修正したい場合は、下記説明をお読みください。


説明図


その外の状況などを図示します。JS上部の設定とあわせて見てください。詳細は略します。


● バグの対処

一応、この場は階層を増やし分離して対応しました。何か他に方法があるかも知れませんが、情報は少ない。

1. 文字陰影をCSSに頼らず、画像の文字にしてしまう。但し画像を用意するのが大変。
2. 文字部分を2段にして、下の文字にBlurフイルターを施す。hidden の影響は受けないようだがすこぶる面倒である。
3. HTML構造を変えるのが手っ取り早いが、CSS記述がふえる。 4. 全て画像にしてCSS3を使用しない。(IEで問題が多すぎるので、私の場合画像での処理が多い)


● JS初期設定値の記載

CSSでの設定値と重複しますが、JSで自動取得していませんので記載ください。その外は自由。


//menu要素の高さ
var menu_H=60;
//ボーダー使用の場合の幅、使用しないときは0
var border_H=2;
//sub-menuの配置位置position-y/CSSとあわせる
var sub_pos_X=50;
//サブメニュー下のスペース 5-10
var bottom_sps=10;

● jquery.backgroundpos.jsの書式


animate部分の例

animate({backgroundPosition:'-45px -60px', ................

この部分は、backgroundpos.js の書式になります。px単位が間違いがすくない

使用jqueryバージョンなどの注意点

動作の関係で、jquery バージョン 1.7 1.8系を、プラグイン jquery.backgroundpos.js バージョン v1.1.0、の組み合わせを推奨します。組み合わせを違わせますと「IE7 8」で正常な動作をしません。
プラグインの組み合わせ詳細は、下記のページを参照ください。

【参考】当方の記事: jQuery HoverMenu 8


● IE7.8 陰影をつけた場合に動く対策

陰影をつけたために自動でpaddingされたのが原因でアニメの際に動いていると想定されます。数値では修正出来ませんので「どうしても気になる」方は、次ぎのようにしてください。


修正する所

//over
function() {

	途中略

	//伸ばす高さを計算
	var h=0;//初期値0
	if (subitem_H[i]) {h=subitem_H[i]+(sub_pos_X-menu_H)+bottom_sps;}
	//プラグインアニメ実行
	item[i].find('.sub-menu').css({'display':'block'});
	item[i].find('.menu-back').animate({backgroundPosition:'-45px -60px','height':menu_H+h},600,function (){
		//
	});
},

高さのアニメ、'height' があると動く、実際は同じ高さなので動かないのですが、
heightアニメを除去するために、アニメ実行部分を連想配列にしてすりかえます

配列、subitem_H[i] にはサブメニューの高さを保存しています
高さがない場合は 'height' 部分を除去してアニメを実行させる

//over
function() {

	途中略

	//伸ばす高さを計算
	var h=0;//初期値0
	if (subitem_H[i]) {h=subitem_H[i]+(sub_pos_X-menu_H)+bottom_sps;}

	var pt={backgroundPosition:'-45px -60px','height':menu_H+h};
	if (!subitem_H[i]) {var pt={backgroundPosition:'-45px -60px'};}

	//プラグインアニメ実行
	item[i].find('.sub-menu').css({'display':'block'});
	item[i].find('.menu-back').animate(pt,600,function (){
		//
	});
},

-------------------------------------------------------

backgroundPosition はプラグイン backgroundpos.js アニメ
'height' は jquery アニメ

{backgroundPosition:'-45px -60px','height':menu_H+h}

2つ一緒に記述しています


中央配置の変更について

初期段階では、中央配置になっています。解除するには JS先頭部分のcenter_setを解除して、CSSの下記部分を削除ください。左揃えになります。


JS

//中央揃えの幅を取得して自動で幅などのCSSを決める
var center_set="";//set none

-------------------------------------------

CSS

/float:leftを削除する、IE6.7での幅取得のためにフロート

#hover-menu ul {
list-style:none;
display:inline-block;
width:auto;
height:60px;
padding:0;
margin:0;
}

右にそろえるならば、JSの中央配置設定解除して
float:right


使用画像

このサンプルでは、アルファチャンネル画像 block_alpha8h.png (200x120)、arrow画像arrow_8b.png (200x20) を使用しています。青色のものは、背景画像のX位置が 0 であっても良いものです。

block_alpha8.png block_alpha8b.png block_alpha8c.png
block_alpha8d.png block_alpha8e.png block_alpha8f.png
block_alpha8g.png block_alpha8h.png 追加交換用画像

arrow_8.png / arrow_8b.png




動作ブラウザを、CSS3にほとんど対応の、Safari Firefox Chrome Opera、に限定したほうが容易です。IE9でこの通りですから、IE10であってもまた問題が出るのでは無いでしょうか。


IEがあると問題が多すぎ修正が大変です。IEに対応しないほうが制作には効率的です。このような状況はいつまで続くのでしょうか?。

以上です。

 


[ この記事のURL ]


タグ:jquery , Effect , memo , series

[ jQuery HoverMenu シリーズ記事 ]

jQuery HoverMenu/112012.11.18
jQuery HoverMenu/102012.11.14
jQuery HoverMenu/92012.11.08
jQuery HoverMenu/82012.11.06
jQuery HoverMenu/72012.11.04
jQuery HoverMenu/62012.11.01
jQuery HoverMenu/52012.10.30
jQuery HoverMenu/42012.10.29
jQuery HoverMenu/32012.10.28
jQuery HoverMenu/22012.10.27
jQuery HoverMenu/12012.10.26

 

ブログ記事一覧

年別アーカイブ一覧



[1]