プロが教える店舗&オフィスのセキュリティ対策術

jQuery初心者でつまずいております…
#navi > ul > li にhoverしたn秒後に、subnaviをslideDownで表示させたいです。
そして、hoverがはずれてsubnaviがslideToggleで戻るまでにもn秒ほしいです。

以下のコードで試したところ、hover時に画面全体に広がるマスク(#hg)は表示されますが、
肝心のsubnaviが表示されません。
また、いずれかのliをhover中に他のliをhoverしようとすると、イベント自体が止まってしまいます。
他のliにhoverした際は、以前hoverしていたliのイベントを中断して、新たにhoverした要素を優先させたいです。

【HTML】
<div id="hg"></div>
<nav id="gnavi">
<ul>
<li>
<a href="javascript:;">タイトル</a>
<div class="subnavi">サブナビ</div>
</li>
<li>
<a href="javascript:;">タイトル</a>
<div class="subnavi">サブナビ</div>
</li>
<li>
<a href="javascript:;">タイトル</a>
<div class="subnavi">サブナビ</div>
</li>
</ul>
</nav>

【jQuery】
$(function() {
$("#navi > ul > li").on({
'mouseenter':function(){
sethover = setTimeout(function(){
$(".subnavi:not(:animated)", this).slideDown(500);$("#hg").stop().fadeIn();
},500);
},
'mouseleave':function(){
sethover = setTimeout(function(){
$(".subnavi",this).slideToggle(500);
$("#hg").stop().fadeToggle();
clearTimeout(sethover);
},400);
}
});
});

【CSS】
#hg {
display: none;
position: absolute;
width: 100%;
height: 100%;
background: #000;
z-index: 40;
filter: alpha(opacity=70);
-moz-opacity: 0.70;
opacity: 0.70;
}
#gnavi {
margin: 0 auto;
box-sizing: border-box;
max-width: 1200px;
height: 65px;
}
#gnavi > ul {
display: flex;
justify-content: space-between;
}
#gnavi > ul > li > a {
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
height: 65px;
padding: 0 1em;
font-size: 16px;
font-weight: bold;
line-height: 1.25em;
color: #000;
}
#gnavi .subnavi {
display: none;
position: absolute;
top: 130px;
right: 0;
left: 0;
width: 100%;
margin: auto;
background: #fff;
box-shadow: 0 15px 15px -15px rgba(0,0,0,0.4) inset;
}

ご教示の程、何卒宜しくお願い致します。

A 回答 (2件)

No1です。



なさりたいことが相変わらず不明なので、勝手な推測ばかりですが、こんなことをなさりたいのかも知れません。
(当たるも八卦を繰り返していても仕方がないので、このへんでやめておきますが…)

※ 仕組みや考え方は、過去2回のご質問で説明した内容と同じです。
※ hoverすると画面が動くのはスクロールバーが表示されるためですが、それはご提示の原文のままの仕組みなので、そのままにしてあります。

<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>
<style type="text/css">
#hg {
display: none;
position: absolute;
width: 100%;
height: 100%;
background: #000;
z-index: -10;
opacity: 0.7;
}
#gnavi {
position: relative;
margin: 0 auto;
box-sizing: border-box;
max-width: 1200px;
height: 65px;
}
#gnavi > ul {
display: flex;
justify-content: space-between;
}
#gnavi > ul > li > a {
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
height: 65px;
padding: 0 1em;
font-size: 16px;
font-weight: bold;
line-height: 1.25em;
color: #000;
margin-bottom: 65px;
}
#gnavi li > a + div {
display: none;
position: absolute;
top: 130px;
right: 0;
left: 0;
width: 100%;
margin: auto;
background: #fff;
box-shadow: 0 15px 15px -15px rgba(0,0,0,0.4) inset;
}
</style>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2. …

<script type="text/javascript">
$(function() {
$("#gnavi>ul>li>a").on('mouseover', function(){
$(this).next('div').stop().slideDown(500);
$('#hg').stop().fadeIn();
}).parent().on('mouseleave', function(){
$('>a+div', this).stop().slideUp(500);
$('#hg').stop().fadeOut();
});
});
</script>
</head>

<body>
<div id="hg"></div>
<nav id="gnavi">
<ul>
<li>
<a href="#">タイトル1</a>
<div>サブナビ1</div>
</li>
<li>
<a href="#">タイトル2</a>
<div>サブナビ2</div>
</li>
<li>
<a href="#">タイトル3</a>
<div>サブナビ3</div>
</li>
</ul>
</nav>
</body>
</html>
    • good
    • 0

こんばんは



>n秒後にイベントを実行した
setTimeoutを使うのなら、第二引数が時間差に該当します。
ですので、
 setTimeout(func, n*1000)
のようになるはずです。
jQueryのアニメーションなら、delay(n*1000) とすることで簡単に時間差を指定できます。

しかしながら、本当になさりたいことは一定時間(=固定の決まった時間)の遅延ではなさそうに思いますけれど、どうなんでしょうね?

ユーザの操作に対応するのに、固定時間(微小時間ならともかく) の遅延で対応することの意味がわかりかねます。
操作に反応するのに1秒、2秒もの差があると、ユーザには操作との関係がわからなくなりますし、その間に別の操作を始めてしまいかねません。
    • good
    • 0
この回答へのお礼

ご回答いただき、ありがとうございます!
固定時間といってもコンマ3秒ほどを考えております。
hoverになった・離れた瞬間に表示されたり消えたりすると使いにくいと思い、若干のタイムラグを付けたいと思っています。

ご指南頂いたとおり、delayでも試したのですが、マウスを素早く動かすとその回数分だけ遅延して表示されてしまい、ちかちかしてナビゲーションとしては使いづらいです…
現状のjQueryだとまだ理想のアニメーションに近いです。
ただ、$("#hg").stop().fadeIn()は正しく表示されて.subnaviがslideDownされないのが分かりません。:not(:animated)の組み合わせが良くない等があるのでしょうか…

もう少し作業してみようと思います。ありがとうございます!

お礼日時:2020/10/06 12:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!