2011-02-06 13 views
0

私は、インラインJavascriptでロードされた既存のメニューシステムを、jQueryのみを使用してより効率的な新しいコードに変換しようとしています。マウスオーバーでスライディングメニューを開いたままにする

私はロールオーバーイメージを持つ横のバーを持っています。私はページに整数値を含む隠しフィールドを持っています。ページが読み込まれると、対応するメニューに画像の「スティッキー」バージョンがロードされ、他のすべてのメニュー項目はマウスで画像をスワップします&を入力します。それには、新しいサイトを作成するたびに変換するのが面倒だった、インラインJavascriptとモンスターJavascriptファイルのトンが読み込まれました。

これをすべてjQueryに変換しました。スティッキメニュー項目のクリックを無効にすることもできました。今ではいくつかの変数を設定し、各サイトのデザインごとに簡単にカスタマイズすることができます。

作業中...

今すぐ新しい問題が発生します。 1つのデザインには、各メニューイメージの下に一連の引き出しがあります。スライディングアニメーションは外部JSファイルによって処理され、メニュードロワ自体はコンテナーDIV内にネストされたコンテンツを含むDIVです。

それで、私はjQueryのために、DIVをアニメーション化し、メニュー画像のマウスのホバーに出し入れする簡単なものを書きました。

問題は、マウスがメニューイメージからドロワーが閉じずにメニュードロワーに移動する問題を解決できないように見えることです。私は "なぜ?"を理解しています...私は内部に入る前に引き出しを閉じるアニメーションを引き起こすイメージを残しています。ホバーアニメーションを引き出しコンテナに適用すると、アニメーションをトリガーするメニューの下にゾーンが作成されるだけで、私はそれも望んでいません。これはjQueryのより複雑な問題になっているようです。これはインラインのJavascriptでうまくいきました...あなたは、マウスを画像から隣接する開いている引き出しに移動するだけで、閉じる関数をトリガーせずに...引き出しのインライン「マウス入力」が取り消されたかのようにイメージの「マウス離脱」。

提案がありますか?

ありがとうございました!


EDIT:

は私が.stop使用してこれを解決信じる(真、偽)画像から引き出しに通過するとき。これにより、アニメーションが停止する前に停止します。通常のアニメーションを開始する前に画像を入力するときと同じです。これは、引き出しを残して画像を入力することによってトリガーされるアニメーションを停止する効果を持ちますが、画像を通常通り入力するだけでは何もしません。より多くのテストを行い、サンプルコードをいくつか投稿します。


EDIT#2:

私はそれが「停止()」と「遅延()」での作業アニメーションを制御する必要があるが、それはあなたが得ることができれば、引き出しの開口部を凍結することが可能ですあなたそれを開くために必要な時間よりも速くマウスを押し込んでください。 150ミリ秒でインストールされます。今は問題を誇張するために300ミリ秒に設定されています。

ここに掲載されている関連コード...

jsfiddle。ネット/ qPLVp/8/


EDIT#3:ニールへ

おかげで、これは今、非常にうまく機能しています。より速いアニメーション速度では、マウスのメニュー画像のオーバーシュートと引き出しの状態が最小限に抑えられます。しかし、それが起こった場合、引き出しはあなたのマウスの下から閉じるよりはるかに良いクローズされません。

http://jsfiddle.net/elusien/PayFw/8/


EDIT#4:再び

ニールのおかげで、これは同じコードのより効率的なバージョンです...

http://jsfiddle.net/PayFw/9/

+0

私たちの助けになるようにjQueryコードとHTMLの関連ビットを表示してください。私は助けることができると思うが、コードを見る必要がある。 – Neil

答えて

1

jsFiddleコードを変更して機能させました。基本的に私はあなたの#menu要素にデータオブジェクトを添付しました。この引き出しを開くとき、オブジェクトは{opening: true}です。引き出しが完全に開いている(アニメーションが完了している)とき、オブジェクトは{opening: false}です。私はあなたが引き出しを入力するときこれをチェックし、それが偽であるならば、私はアニメーションを止める。それが本当であれば私はアニメーションを止めません。

コードは次のとおりです。

function enter(event) { // mouseenter IMG 
     // removed image rollover code 

     $('#menu').data({opening: true}).stop(true, false).animate({ 
      top: '0', 
      opacity: 1 
     },{ 
      duration: 300 // slow the opening of the drawer 
     }, 
     function(){$(this).data({opening: false});} 
     ); 
    }; 
    function leave(event) { // mouseout IMG 
     // removed image rollover code 

     $('#menu').delay(400).animate({ 
      top: '-'+$ht+'px', 
      opacity: 0 
     },{ 
      duration: 600 
     }); 
    }; 

    $('#menu').hover(
     function(){ // mouseenter Menu drawer 
      if (!$(this).data('opening')) { 
       $(this).stop(true, false); 
      } 
     }, 
     function(){ // mouseout Menu drawer 
      $(this).delay(400).animate({ 
       top: '-'+$ht+'px', 
       opacity: 0 
      },{ 
       duration: 600  
      }); 

     } 
    ); 

これは現在正常に動作します。これに照らしてあなたの「遅れ」のいくつかをやり直したいかもしれません。

+0

http://jsfiddle.net/PayFw/こんにちはニール - 上記は確かにフリーズの問題を修正します。しかし、アニメーションが完了した後にマウスがドロワに移動すると、ドロワは開いたままになりません。メニューイメージにカーソルを置き、引き出しが開くのを待ちます。マウスを引き出しに引き、引き出しを閉じます。あなたは確かに正しい道に私を置いてきましたが、何らかの調整を加えれば、私はこれを得ることができると思います。ありがとうございました! – Sparky

+0

あなたの前のコードに基づいて、私はアイデアを持っています、Neil ...私はそれを並べ替えると私はつまらない場合は叫ぶよ...私はあなたの時間を感謝し、それを解決する。私はいずれかの方法でポストバックします。 – Sparky

+0

Neil-私はそれを書き直しました。私は何かクールなものがあると思っていましたが、マウスをあまりに速く動かすだけでそれが壊れました。あなたがそれを持っている方法では、コールバック関数は決して起動しません(私は思う構文の問題)。その部分は修正されています。アニメーション中にメニューイメージをオーバーシュートすると、ドロワは単に停止して閉じます。引き出しが完全に開いたら、引き出し内を移動することができます。 (理想的には、アニメーション中にマウスが入ると、引き出しを開いて開いたままにしておきたい)。継続時間を長くすると、障害の可能性が低くなります。あなたの知恵にも興味があります... [link](http://jsfiddle.net/PayFw/5/) – Sparky

0

それはのように思えますあなたは現在または将来DOMイベントにハンドラを添付する.delegate()関数を探しています:

あなたがここに.delegate()関数とそのバディ.live()についての詳細を読むことができ
$(".menuItem").delegate(".subMenu","hover", function(){ $(this).show(); }); 

:コードを見ることなくhttp://api.jquery.com/delegate/

+0

興味深い。これは、私がやっている「ストップ」よりも優れたアプローチだと思いますか? (上記の私の編集とNeilの提案を参照してください)。デリゲートは私には新しく、私はそれの周りに私の頭を包んで苦労している。 – Sparky

0

次のことがうまくいくかどうかを知ることは困難である:

hover()は引数として2つの関数をとります。最初のものは画像を入力するときに実行されます。あなたがイメージを残すとき。

おそらく、引き出しを隠す(閉じた)第2の機能を設定しました。私はhide()の前に小さな遅延(例えばdelay(100))を追加し、(最初の関数の引数で)ドロワーイベントをアニメーションキューを停止するように設定しますstop(true, true) - これはドロワーが閉じられるのを止め、それを終了するときに引き出しを閉じます。

+0

ありがとうございましたNeil!...私はあなたの答えを読む前に "停止"を考えましたが、小さな遅延のあなたのアイデアはこれに非常に賢い追加のように思えます。キャンセルされたアニメーションを完成させたくないので、私は "stop(true、false)"を使用する必要があります。 SafariとFirefoxで動作するようです...次にExplorerでテストします。 – Sparky

+0

StackOverflowの新機能で、すべてのコードをどこに投稿するのかわかりません...小さな問題で作業しています...開いている間にマウスを画像の上に移動してドロワに移動すると、フリーズします。私はこの状況を減らすためにかなり早く(200)開きますが、それは存在します。 – Sparky

+0

質問自体にコードを入れることができます(コードを使用するときは "code"記号を使用してください)。それともHTMLやCSSと共に「www.jsfiddle.net」に置いて保存したときに取得したWebアドレスを投稿すると、人々は簡単に「再生」できるようになります。 – Neil

1

スパークリー、

私は、いろいろなやり方で思いついた。基本的に "ボタン"と "説明"の上に透明なマスクを配置し、これに対して "mouseleave"イベントを使用します。

HTML:

<body> 
<div id="Container" class="menuContainer" style="position: relative"> 
<div id="menumask">&nbsp;</div> 
<!-- this simulates the menu rollover image --> 
<div id="menuitem" style="position:absolute; background-color:#ff00ff; top:10px; width:200px; height:50px; text-align:center;"> 
    <b>MENU ITEM</b> 
</div> 

<!-- this is the drawer --> 
    <div id="menu" class="menuContent"> 
     <br/> 
     <p>Content of the menu drawer.</p> 
     <br/> 
     <p>Bla bla bla </p> 
     <br/> 
     <p>Bla bla bla Bla.</p> 
     <br/> 
     <p>Bla bla bla Bla bla.</p> 
     <br/> 
     <p>Bla bla bla Bla bla bla Bla bla.</p> 
    </div> 

Javascriptを:

$(document).ready(function() { 
    $('#menuitem').bind('mouseenter', enter); 
    $('#menumask').bind('mouseleave', leave); 

    $('#menu').css({ 
     height: '500px', 
     position: 'absolute', 
     paddingTop: '50px', 
     width: '200px', 
     backgroundColor: '#080', 
     zIndex: -1 
    }).hide(); 
    $('#menumask').css({ 
     height: '550px', 
     width: '200px', 
     opacity: 0.99, 
     position: 'absolute', 
     fontSize: '20000px', 
     overflow: 'hidden', 
     zIndex: 2 
    }).hide(); 

    function enter(){ 
     $('#menumask').show(); 
     $('#menu').stop(true,true).animate({height: 500}, 'slow'); 
    }; 
    function leave(){ 
     $('#menumask').hide(); 
     $('#menu').stop(true,true).slideUp({height: 0}, 'slow');}; 
}); 

あなたのメニューシステムの基礎としてこれを使用することができます。

よろしく ニール

+0

ありがとうございましたNeil!私は一度それを試してみる機会があった後に私はポストバックします。 – Sparky

+0

このコードは本当にうまく見えますが、このサイトではすべてのボタンのマスクを作るつもりはありません。しかし、それは確かにこのコンセプトの多くの問題を解決するので、将来のサイトのために保存されるつもりです。ありがとうございました! – Sparky

0

同じことを達成しようとしながら、ちょっと私はこの記事につまずきました。今は2017、.delegateが廃止され、移行がまだ効果的でないかどうかを追跡するためにデータを使用するため、解決策を残すと思った。

キーはmouseleaveコールバックに渡された要素を使用してelement.relatedTargetを取得していました。

$('.myMouseoverElements').on('mouseover', function() {   

    activeElements = $('.elements.to.open') 
    activeElements.addClass('open') 

    activeElements.on('mouseleave', function(element) { 

    var sustainElements = $('.elements.to.sustain.mouseover') 
    var drawerShouldClose = !$(element.relatedTarget).is(sustainElements) 

    if (drawerShouldClose) { 
     activeElements.removeClass("open") 
     activeElements.off("mouseleave") 
    } 
    }) 
}) 

ありがとうございます!

関連する問題