jQueryでポップアップの中にポップアップ

このQ&Aのポイント
  • ポップアップ内でのhoverイベントを有効にするためには、liveを使用する必要があります。
  • 後から追加された要素(ポップアップ)内でのhoverイベントを適用させるためには、mouseenterとmouseleaveを分けて指定する必要があります。
  • ポップアップの上にカーソルを合わせることができずに困っています。
回答を見る
  • ベストアンサー

jQueryでポップアップの中にポップアップ

<html> <head></head> <style type="text/css"> .popup { position:absolute;bottom:0;left:0;width:300px;padding:1px 5px;border:solid 1px #000;background:#fff;} </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $('.b').live({ /* <= bind? */ mouseenter:function(){ var target = $( $(this).children().filter('.c').attr('href') ); $(this).css('position','relative'); $(this).append('<div class="popup">'+target.html()+'</div>'); }, mouseleave:function(){ $(this).css('position','static'); $(this).children().filter('div').remove(); } }); }); </script> <body> <div id="a1"><p>a1a1a1</p></div> <div id="a2"><p>a2a2<span class="b"><a href="#a1" class="c">#a1</a></span>a2</p></div> <div id="a3"><p>a3<span class="b"><a href="#a2" class="c">#a2</a></span>a3a3</p></div> </body> </html> このような感じで、#a2にマウスカーソルを合わせたらid="a2"の内容が吹き出しのような感じでポップアップし、 その中に含まれる#a1にマウスカーソルを合わせたらそこからさらにid="a1の内容がポップアップする仕組みを作りたいのですが、 ポップアップの上にマウスカーソルを合わせることができずに困っています。 参考:jQuery の hover() について調べたことのまとめ http://d.hatena.ne.jp/tilfin/20080615/1213608859 参考:.live()でhoverイベントに複数の関数をバインドできない http://jsdo.it/cancer6/mh9t 自分で調べてみて分かったことは ・hover(fn1,fn2)はfn1=mouseover,fn2=mouseoutではなくfn1=mouseenter,fn2=mouseleave ・後から追加した要素(ポップアップ)の中の要素にもhoverを有効にするにliveでhoverを設定する必要がある ・liveでhoverイベントを指定するときはmouseenter,mouseleaveの2つに分けて指定する必要がある 上記のコードを保存して見ていただけると分かると思うのですが、 liveにするとポップアップの上にカーソルを合わせることができず、 bindにするとポップアップの上にカーソルを合わせることができます。 ポップアップはclass="b"の子要素となるようにしているので、 ポップアップにマウスカーソルが合わさっている状態=class="b"からmouseleaveしてない状態となっていると思うのですが…。 どのようにすれば「後から追加された要素(ポップアップ)」内にもhoverイベントを適用させつつ、 「後から追加された要素(ポップアップ)」内にマウスカーソルを乗せられる状態にできますか? よろしくお願い致します。

この投稿のマルチメディアは削除されているためご覧いただけません。

質問者が選んだベストアンサー

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

#1です。 簡単なテストをしてみましたが、対象が孫以上の入れ子になっていると、 子までだとmouseenter/leaveの意味通りになるのですが、入れ子の時には、孫のmouseenterが発生する時に子のmouseleaveが発生しているようです。(mouseover/outと同じような感じ) それなので、mouseenter/leaveを使っていても自前でチェックをしてあげる必要があるみたい。 liveに自前のチェックを追加した形で、試みに作成してみました。 $(function(nestCheck){ $('.b').live({ mouseenter:function(e){ if(nestCheck(this, e)) $(this).css("position","relative").append('<div class="popup">'+ $($(this).children('.c').attr('href')).html()+'</div>'); }, mouseleave:function(e){ if(nestCheck(this, e)) $(this).css("position","static").children('div.popup').remove(); } }); }(function(parent, e){ for(var node=e.relatedTarget, flag=true; node; node=node.parentNode) if(node===parent) { flag=false; break; } return flag; }) ); 多分、見た目は意図通りの動作ではないかと思います。 しかしながら、どうも孫のmauseleave時に(子ではなく)親のmouseenterを完全には除けていないようで、あるマウスの動きのときにpopupが一時的に複数できた状態になるみたい。見かけ上は重なっているしmouseoutで全て削除されるのでわからないのですが、このままだと気持ち悪いですね。 もう少し考えないとダメみたいですが、何かのご参考にでもなれば。

php_noob
質問者

お礼

回答ありがとうございました。 とても参考になりました。

その他の回答 (1)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

ちゃんと確認していませんので、半分は想像での回答ですが… mouseenter、mouseleaveのイベントが伝播するようになっているのか確認していませんが、多分そうだとして… liveで設定しておいて、作成される「a2a2#a1a2」のポップアップのの中のリンク(#a2)にmouseenterが発生すると、<div id="a3">は以下のような構成になります。 (どのタイミングでとらえるかで、若干変わるかも) <div id="a3">  <p>a3   <span class="b" style="position: absolute;">    <a class="c" href="#a2">#a2</a>    <div class="popup">     <p>a2a2      <span class="b" style="position: absolute;">       <a class="c" href="#a1">#a1</a>       <div class="popup">        <p>a1a1a1</p>       </div>      </span>      a2     </p>    </div>    <div class="popup">     <p>a2a2      <span class="b">       <a class="c" href="#a1">#a1</a>      </span>      a2     </p>    </div>   </span>   a3a3  </p> </div> 前半の入れ子の関係は意図なさっている通りと思いますが、mouseenterが元の親要素に伝播して、a2a2以下のpopupがもう一つ作成されていると想像されます。 この要素が表示されても、表示上は下にある同じものとまったく重なって表示されるために見た目には分かりません。 しかし、下側になったpopup内にある<span calss="b">からみるとmouseleaveが発生していることになるため、この一連のイベント処理の中でdiv要素が全て消されているということになっているのではないかと想像します。 表示側と、消す側(現在はまとめて消す処理になっている)が対になるようにしてあげることと、イベントの伝播に対して余分な処理をしないような工夫をすれば良いのではないでしょうか? 最初にも書きましたように、きちんと確認してはいませんので、はずしているかも知れません。

php_noob
質問者

補足

ご回答ありがとうございました。 CSS部分を以下のように変更すると、ポップアップがちょっとずれて確認しやすいかと思います。 .popup {position:absolute;bottom:20px;left:20px;width:30em;padding:1px 5px;border:solid 1px #000;background:#fff;} div{padding:10px 0;} .b{padding:10px;background:#eee;} Firefoxのfirebugアドオンでmouseenter時のDOMの変化を確認したところ、 .popupが2つ以上生成されるという減少は確認されませんでした。 最終的に次のようにすることでいちおう考えていたものができました。 <html> <head></head> <style type="text/css"> .popup {position:absolute;bottom:20px;left:20px;width:30em;padding:1px 5px;border:solid 1px #000;background:#fff;} div{padding:10px 0;} .b{padding:10px;background:#eee;} </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script> <script type="text/javascript"> $.fn.extend({ popupEvent : function(){ $('.b',this).bind({ mouseenter:function(){ $(this).css('position','relative').append('<div class="popup">'+$( $(this).children().filter('.c').attr('href') ).html()+'</div>').popupEvent(); $('#log').append('mouseenter<br>'); }, mouseleave:function(){ $(this).css('position','static').children().filter('div').remove(); $('#log').append('mouseleave<br>'); } }); } }); $(function(){ $('div').popupEvent(); }); </script> <body> <div id="a1"><p>a1a1a1</p></div> <div id="a2"><p>a2a2a2<span class="b"><a href="#a1" class="c">#a1</a></span></p></div> <div id="a3"><p>a3a3<span class="b"><a href="#a2" class="c">#a2</a></span>a3a3<span class="b"><a href="#a1" class="c">#a1</a></span>a3a3a3</p></div> <div id="a4"><p>a4<span class="b"><a href="#a3" class="c">#a3</a></span>a4a4</p></div> <div id="log"> </div> </body> </html> 後から追加された要素に.live()を使わずに.bind()でイベントを適用させられると知り、 試しにやってみたのですが、なぜこれでできて、.live()でできないのかがまだよくわかりません。 もしよろしければ何かアドバイスをいただけると助かります。 引き続きよろしくお願い致します。

関連するQ&A

  • jqueryを使ってポップアップを作ろうとしています。

    jqueryを使ってポップアップを作ろうとしています。 アイコンにマウスオーバーでポップアップ表示、ポップアップの×をクリックしてポップアップ削除という動きまではできています。 しかしマウスオーバーのアイコンはul liの中にあるのに、ポップアップはulの外に置かれているため、thisが使えず、アイコンにマウスオーバーすると全てのポップアップが表示されてしまいます。 これをマスウオーバーしたアイコンのポップアップのみ表示できるようにしたいです。 下記にソースになります。表示させたいのはアイコン02にカーソルを合わせた場合のみになります。 よろしくお願いいたします。 JS ---------------------------------------------------------------- $(function(){ $(".popup").hide(); $(".box ul li.icon02").mouseover(function(){ $(".popup").fadeIn("fast").css({ top:10+"px", left:-95+"px"}); }); $(".popup img.closed").click(function(){ $(".popup").fadeOut("fast"); }); }); html ---------------------------------------------------------------- <div class="box"> <div class="boxIn"> <ul> <li class="ico01"><a href="#"><img src="アイコン1url" /></a></li> <li class="ico02"><a href="#"><img src="アイコン2url" /></a></li> <li class="ico03"><a href="#"><img src="アイコン3url" /></a></li> </ul> <!--▼pop-up部分--> <div class="popup"> <p>●●<img src="クローズボタンurl" alt="close" width="12" height="12" class="closed" /> </p> <div class="popInner"> <p>ポップアップの中身</p> <!--#popInner--> </div> <!--#popup--> </div> <!--▲pop-up部分ここまで--> <!--#boxIn--> </div> <!--#box--> </div> 以下 <div class="box"> ~~同じ構成要素の繰り返し。

  • jQueryのmouseenterについて

    jQueryで、#div1 にmouseenter,mouseleaveを設定していますが、#div1の領域の一部に重なって表示している別の要素(#div1の子要素ではない)があり、その上にマウスが乗るとmouseleaveが発動します。 これを、発動しないようにする方法はあるでしょうか?

  • jQueryのポップアップでデザインがおしゃれなものはありませんか?

    jQueryのポップアップでデザインがおしゃれなものはありませんか? いろいろライブラリを探してみているのですがいいものが見つかりません。 一応ポップアップを探しているのですが用途としては div要素に載った時そのことの説明文を出したいと思っています。 ちょっとしゃれているからおススメ!みたいなのがあったら教えてください。 マウスのある位置から右上側に吹き出しが理想的です

  • jQuery class要素を盛り込むには

    画像をマウスオーバーで変化させるコードを、こちらで教えていただいたアドバイスに従って以下の内容で行っています。 $(function(){ $('span img').hover(function(){ $(this).attr('src', $(this).attr('src').replace('.jpg', 'x.jpg')); }, function(){ if (!$(this).hasClass('currentPage')) { $(this).attr('src', $(this).attr('src').replace('x.jpg', '.jpg')); } }); }); BODY部分は、 <SPAN><IMG src="画像.jpg"></SPAN> となっています。 けれど、よくよく考えると、マウスオーバーしたくない画像でも<SPAN>の中に記述していたらコードの影響をうけて、存在しない(マウスオーバー後の)画像を読み込もうとしてしまいます。 基本的な質問で申し訳ないのですが、 区別するため、例えば、マウスオーバーさせたい<SPAN>にはclass要素を入れて、 <SPAN class="change"><IMG src="画像.jpg"></SPAN> としたとして、上記のコードの、 $('span img').hover(function(){ の辺りをどうにか変えればいいように思うのですがよくわかりません。 基本的すぎて申し訳ありませんが、よろしくお願いします。

  • jquery ドロップダウン・メニュー

    jquery ドロップダウン・メニュー ドロップダウン・メニューを作成しています。一番最後のtwitter部分だけにクリック動作を適用させたいのですが、 思うように表示が出来ません。 どうしたらいいのか、教えてください。 <script src="/jquery/jquery-1.4.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function() { $('li.twitter').click(function() { if ($(this).hasClass('click')) { $(this).removeClass('click'); } else { $('.click').removeClass('click'); $(this).addClass('click'); } }); $('div.drop').hover( function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); }); }); </script> <div id="feed"> <ul class="aux"> <li class="rss1"> <a href="http">RSS1</a> </li> <li class="rss2"> <a href="http">RSS2</a> </li> <li class="rss3"> <a href="http">RSS3</a> </li> <li class="twitter"> <a href="#"><span>Twitter</span></a> <div class="drop"> <p><strong>TW1</strong> <a href="http://www.twitter.com/●●" target="_blank"><img src="http://abcde/a.png" />Follow Me</a> </p> <p> <strong>TW2</strong> <a href="http://www.twitter.com/●●●●●" target="_blank"><img src="http://abcde/b.jpg" />Follow Me</a> </p> </div> </li> </ul> </div>

  • jQueryで同じ要素の先頭へ親要素を移動したい

    下記のとき、<span>□</span>をクリックしたら、pタグの一番上へ要素を移動するにはどうすればよいでしょうか? 変更前 <section>  <div>★</div>  <p><span>☆</span></p>  <p><span>■</span></p>  <p><span>□</span></p> 変更後 <section>  <div>★</div>  <p><span>□</span></p>  <p><span>☆</span></p>  <p><span>■</span></p> ■やりたいこと ・<section>はそれぞれ複数あるので、クリックした地点からの相対パスで、一番上要素を指定したいです ・「$(this).parent()」を、「$(this).parent()」のpタグ先頭の先頭へ追加すればよい? どうやって?

  • jQuery|:not(:animated)

    こんにちは、 jQueryにおいて、要素に対して.hoverをかけ、:not(:animated)の指定をした場合、対象要素上で素早くマウスを滑らせると、アニメーションが終了する前にmouseleaveしてしまい、mouseenterの状態でアニメーションが止まってしまいます。(下記URL参照) http://ref.andwax.com/Untitled-1.html このように棚に並べたパンすべてに同様の処理を行う予定なのですが、前述の不具合が解消できなければアイディアそのものを変更を迫られることになると思われます。何か対処方法をご存じでしたら、お伺いできませんでしょうか。全く違う方法で同様の処理を行うアイディアをご存じでしたら、そちらもお聞かせいただけるとありがたいです。 また、area要素にはcursorプロパティが効かないようなのですが、カーソルを出現させるためのアイディアがありましたら、伺わせてください。

  • JQueryのセレクタ

    jqueryでセレクタの取得をしたいのですがうまくいきません div要素の中のspan要素を取得したいのですがclassで取得すると重いのでid属性で場所を限定してからclass属性で絞り込みたいです こんな感じにしたらだめでした $("#hoge.foo").html('ほげ'); html <div id=hoge> <span class=foo></span> </div>

  • JQueryを使ってcssを書き換え

    何となくコードを見てさわる程度の初心者です。 以下のようなソースを組みました。 <div id="slide"> <a href="01.htm"><img src="01.jpg" alt="01" id="alttxt" /></a> </div> <div id="slidenavi"> <ul> <li><a href="01.html"><img src="s_01.jpg" alt="01" class="b_01.jpg" /></a><span class="active"></span></li> <li><a href="02.htm"><img src="s_02.jpg" alt="02" class="b_02.jpg" /></a><span class="active"></span></li> <li><a href="03.html"><img src="s_03.jpg" alt="03" class="b_03.jpg" /></a><span class="active"></span></li> </ul> </div> #slideがメインエリアで、#slidenaviがメインエリアの画像とリンク先を切り替えるナビゲーションボタンになっています。 ナビに連動したメインエリア用の画像ファイル名は #slidenavi の img の classに入れておいて、それを読み込んで代入するというおかしなやり方で呼び出していますが、ここまではうまくいきました。 問題はここからです。 最初の状態では<span class="active"></span>はcssの設定でdisplay: noneとしてあります。 そして#slidenaviのボタンにマウスが乗ると、その部分の<span class="active"></span>をdisplay: blockとして表示したいのですが、これがどうしてもうまくいきません。 この部分も含めて、おかしな書き方になっている部分があれば教えてもらえないでしょうか。 jsファイルは以下の通りです。 $(function(){ $('#slidenavi ul li a').fadeTo(0,0.4); $('#slidenavi ul li a').hover(function(){ $(this).fadeTo(300,1.0); }, function(){ $(this).fadeTo(300,0.4); }) $('#slidenavi ul li img').mouseover(function(){ var bglink = $(this).attr("class"); var altTxt = $(this).attr("alt"); $("#slide img").attr("src","images/home/main/"+bglink); $("#slide img").attr("alt",altTxt); $("#slide span.active").css("display","block"); }); $('#slidenavi ul li a').mouseover(function(){ var Href = $(this).attr('href'); var Tget = $(this).attr('target'); $("#slide a").attr("href", Href); $("#slide a").attr("target", Tget); $("#slide a").click(function() { window.open(Href,'_self'); return false; }); }); });

  • 文章のマークアップについて

    <p><span class="red">「今日は寒いね」</span><br>  彼はそう言って笑った。</p> <p><span class="blue">「あ…、雪だ」</span></p> ↑このような使い方は誤り…。 かと言って <div class="red">「今日は寒いね」</div>  彼はそう言って笑った。<br>  ←この部分だけCSSで指定したフォントスタイルが適用されない。 <div class="blue">あ…、雪だ」</div> <div class="red">「今日は寒いね」</div> <div> 彼はそう言って笑った。<div> <br> <div class="blue">「そうだね」<div> ↑これでは少しこの会話が続いた時に「div病(?)」テキストに書いてありました。 全て同じフォントスタイルを使い且つ1行空けたい場合はどうマークアップすれば良いのでしょうか。 HTML初心者のweb作家です。 タグと具体例を示して頂けるとありがたいです。

    • ベストアンサー
    • HTML

専門家に質問してみよう