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触发处理程序两次。相反,您应该做的是:

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

您可能需要考虑使用 jquery 的 livequery 插件,它改进了 DOM 元素的事件绑定/处理。因此,您的示例可以重构为如下所示:

编辑: 更改路径以查找包含两者的父元素.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/(forked the OPs fiddle)​</p>

于 2012-10-16T17:41:09.710 回答
0

我不太明白你描述的行为,但让我印象深刻的一件事是在你的鼠标离开时你正在设置一个 setTimeout。除非您清除它,否则此 setTimeout 将在 3 秒内触发。所以我确实看到发生的是,您可以将鼠标移入.dropcart,然后将不透明度设置为 0.5 并设置计时器。然后,如果您将鼠标移回.dropcart,不透明度会回到 1,但.dropcart在计时器触发时仍会向上滑动。如果您不断地在鼠标中进出鼠标,.dropcart您最终可能会设置一堆计时器,这些计时器会以看似随机的间隔触发,并且真的会扰乱您的用户体验。

您需要做的是,当您执行此操作时,setTimeout它会返回一个 timeoutID。您需要将其存储在一个变量中,以便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 回答