0

私のスクリプトは機能しますが、私が抱えている問題は、close-but 関数を使用すると div が非表示になりますが、数秒後に div がスライドダウンすることです。if ステートメントのようなものを見逃していますか? ありがとうございました。

$(document).ready(function() {
    $(".cart").hover(function() {
        $(".dropcart").slideDown('slow');
     });
    $('.dropcart').mouseleave(function() {
        $('.dropcart').css({
            'opacity': '.5'
        }, setTimeout(function() {
            $('.dropcart').slideUp('slow');
        }, 3000));
         });
    $('.dropcart').mouseenter(function() {
        $('.dropcart').css({
            'opacity': '1'
        });
    });
        $('.close-but').click( function() {
    $('.dropcart').hide();
    });
    });
4

2 に答える 2

0

hovermouseenter/mouseleaveハンドラーの省略形です( http://api.jquery.com/hover/を参照)。

あなたが発見したように、イベントハンドラーの動作にはいくつかの癖があるため、より複雑な対話にはホバーを使用しない傾向があります。イベント ハンドラーをバインドしhoverてハンドラーを 2 回起動することがわかりました。代わりに、次のことを行う必要があります。

$('.cart').mouseenter( function(){
    // Your state behaviour code here..
} ).mouseleave( function(){
    // Your state behaviour code here...
} );

DOM 要素のイベント バインディング/処理を改善する jquery の livequery プラグインを使用することを検討してください。したがって、例は次のようにリファクタリングできます。

編集:.cartと の両方を 含む親要素を見つけるようにパスを変更しました.dropcart

$('.cart').livequery( function(){
    var obj      = $( this ).closest('.float-left'); // The cart container element
    var dropcart = obj.find('.dropcart'); // Child of .float-left
    var close    = dropcart.find('.close-but');  // Child of dropcart

    // Handle cart mouseenter event
    obj.mouseenter( function(){
        dropcart.slideDown(300);
    } );

    // Handle cart moseenter/mouseleave events
    dropcart.mouseenter( function(){
        // your behaviour here...
    } ).mouseleave( function(){
        // your behaviour here...
        // Read up on jQuery's delay() method: http://api.jquery.com/delay/
        dropcart.delay(800).slideUp(256);
    } );

    // Handle the close button
    close.click( function(){
        dropcart.hide(); // or dropcart.mouseleave(); // triggers the mouseleave event handler
    } );

} );

アップデート

最初のコメントにはフィドルがありませんでしたが、構造を理解したので、上記の例を反映するように修正しました (上記の修正を参照)。さらに、次のことをお勧めします。

  1. 包含要素に ID または共通クラスを追加します class="cart-container float-left"id="cart-container"
  2. そこに表示されるコンテンツを考慮して、マークアップをもう少し意味のあるものにリファクタリングすることを検討してください。(一部の人々は、JS 拡張機能でそれを行うことにほとんど価値がないと主張することを知っていますが、それでも、それを行うのは良い習慣だと思います)。

HTML リファクタリングの例は次のようになります。

<div class="item-container right">
    <img src="http://news.worldwild.org/wp-content/uploads/2008/09/red_panda.jpg">

    <div class="cart-items">
        <h3>Cart Items: <span class="cart-items-count">10</span></h3>
        <div class="dropcart">
            <dl class="cart-items-list">
                <dt>Items:</dt>
                <dd>10</dd>
                <dt>Price:</dt>
                <dd>$5.00</dd>
            </dl>
            <a href="#" class="close" title="close">x</a>
        </div>
    </div>
</div>​

サポートする CSS:

.right {
    float: right;
}

.item-container > img {
    display: block;
    margin: 0 0 10px 0; padding :0; 
    border: 0;

    width: 100px; height: auto;
}

.item-container .cart-items {
    display: block;
    background: #222;
    color: #fff;
}

.cart-items {
    display: block;
    margin: 0; padding :0; 
}

.cart-items > h3 {
    cursor: pointer;
}

.cart-items-list dt {
    display: inline;
    float: left;
    clear: right;
}

.cart-items-list dd {
        text-align: right;
}

.dropcart .close {
    display: block;
    padding: 0 10px;

    font-weight: bold;
    text-align: right;

    color: #fff;
}​

jQuery スクリプトは次のようになります。

jQuery( function(){

    $('.item-container').livequery( function(){
        var obj      = $( this ).find('.cart-items'); // The cart container element
        var dropcart = obj.find('.dropcart'); // Child of .float-left
        var close    = dropcart.find('.close');  // Child of dropcart

        dropcart.hide();

        // Handle cart mouseenter event
        obj.mouseenter( function(){
            dropcart.slideDown(300);
        } );

        // Handle cart moseenter/mouseleave events
        dropcart.mouseenter( function(){
            // your behaviour here...
        } ).mouseleave( function(){
            // your behaviour here...
            // Read up on jQuery's delay() method: http://api.jquery.com/delay/
            dropcart.slideUp(256);
        } );

        // Handle the close button
        close.click( function(){
            dropcart.mouseleave( function(e){ return false; }); // triggers the mouseleave event handler
            dropcart.hide();
        } );

    } );

} );
​

ここで実際の動作を確認できます: http://jsfiddle.net/kwbbh/2/ (OPs フィドルをフォーク) </p>

于 2012-10-16T17:41:09.710 に答える
0

あなたが説明した動作はよくわかりませんが、私を襲ったことの1つは、setTimeoutを設定しているマウスリーブです。この setTimeout は、クリアしない限り 3 秒で起動します。だから私が見ているのは、あなたがマウスインしてから.dropcart、マウスアウトして不透明度を0.5に設定し、タイマーを設定できるということです。次に、マウスを に戻す.dropcartと、不透明度は 1 に戻りますが.dropcart、タイマーが起動すると はスライドします。マウスを出し入れし続けると.dropcart、一見ランダムな間隔で起動する一連のタイマーが設定され、ユーザー エクスペリエンスが大幅に台無しになる可能性があります。

あなたがする必要があるsetTimeoutのは、タイムアウトIDを返すときです。clearTimeoutこれを変数に格納して、タイムアウトをキャンセルすることを決定したときに渡すことができるようにする必要があります。例えば:

var timerID = 0;

$('.dropcart').mouseleave(function() {
    $('.dropcart').css({
        'opacity': '.5'
    });
    if (timerID)
        clearTimeout(timerID);        // stop multiple timers running at once!
    timerID = setTimeout(function() {
        $('.dropcart').slideUp('slow');
        }, 3000));
    });
$('.dropcart').mouseenter(function() {
    if (timerID)
        clearTimeout(timerID);
    $('.dropcart').css({
        'opacity': '1'
    });
});

このフィドルを参照してください

于 2012-10-16T18:59:51.360 に答える