Jquery Slide Up问题

时间:2012-10-16 17:14:43

标签: jquery hide slideup

所以我的脚本有效,但我遇到的问题是,当我使用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();
    });
    });

2 个答案:

答案 0 :(得分: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增强功能这样做没什么价值,但我仍然认为这是一个很好的习惯。)
  3. 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/(分叉OP小提琴)     

答案 1 :(得分: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'
    });
});

请参阅此fiddle