【问题标题】:jQuery add class on mouseenter and remove it 500ms after mouseoutjQuery在mouseenter上添加类并在mouseout后500ms将其删除
【发布时间】:2013-08-29 14:55:18
【问题描述】:

我有一个小菜单,想在悬停时将类添加到子菜单项中。检查你会理解的代码:

HTML

<ul class="root">
  <li>Menu1
    <ul class="submenu">
    <li>Menu11</li>
    <li>Menu12</li>
    </ul>
  </li>
  <li>Menu2
    <ul class="submenu">
    <li>Menu21</li>
    <li>Menu22</li>
    </ul>
  </li>
</ul>

JS

$('.root li').mouseenter( function( e1 ) {
    var thisItem = $(this);

    setTimeout( function( e1 ) {

        if ( $(thisItem).children().hasClass('open') ) { 
            return; 
        } else {
            $(thisItem).children().addClass('open');
            $(thisItem).siblings().children().removeClass('open');
        } 

    }, 200 );

}).mouseleave( function( e2 ) {
    var thisItem = $(this);
    setTimeout( function( e2 ) {
        if ( !$(thisItem).children().hasClass('open') ) { return; } else {                                  
            $(thisItem).children().removeClass('open'); 
        }
    }, 500 );
}); 

一些 CSS

.root li { display: inline-block; background: #eee; color: #333 }   
.root li:hover { background: #333; color: #fff }    
.submenu li { clear: both }

.root li ul {display: none}
.root li ul.open {display: block}

问题

当鼠标移出 menu12 或 menu22 并重新进入时,在鼠标移出后的 500ms 超时期间,子菜单会冒泡并最终关闭。

小提琴

http://jsfiddle.net/5G3BH/12/

感谢您的回复

【问题讨论】:

    标签: javascript jquery settimeout mouseover addclass


    【解决方案1】:

    你需要在 mouseenter 和 mouseleave 上清除设置的计时器

    $('.root li').mouseenter(function (e1) {
        var thisItem = $(this);
        clearTimeout(thisItem.data('hoverTimer'))
        var timer = setTimeout(function (e1) {
    
            if ($(thisItem).children().hasClass('open')) {
                return;
            } else {
                $(thisItem).children().addClass('open');
                $(thisItem).siblings().children().removeClass('open');
            }
    
        }, 200);
        thisItem.data('hoverTimer', timer)
    }).mouseleave(function (e2) {
        var thisItem = $(this);
        clearTimeout(thisItem.data('hoverTimer'))
        var timer = setTimeout(function (e2) {
            if (!$(thisItem).children().hasClass('open')) {
                return;
            } else {
                $(thisItem).children().removeClass('open');
            }
        }, 500);
        thisItem.data('hoverTimer', timer)
    });
    

    演示:Fiddle

    【讨论】:

      【解决方案2】:

      DEMO

      使用clearTimeout清除setTimeout

      $('.root li').mouseenter(function (e1) {
          var thisItem = $(this);
          clearTimeout(x);
      
          y = setTimeout(function (e1) {
      
              if ($(thisItem).children().hasClass('open')) {
                  return;
              } else {
                  $(thisItem).children().addClass('open');
                  $(thisItem).siblings().children().removeClass('open');
              }
      
          }, 200);
      
      }).mouseleave(function (e2) {
          var thisItem = $(this);
          clearTimeout(y);
          x = setTimeout(function (e2) {
              if (!$(thisItem).children().hasClass('open')) {
                  return;
              } else {
                  $(thisItem).children().removeClass('open');
              }
          }, 500);
      });
      

      【讨论】:

      • @Danny 我是第一个回答检查时间的人
      • 谢谢,但是这个没用,抱歉。我标记的答案在第一次点击时有效。
      • 是的,现在您的演示也可以使用了。我的 FF 似乎有问题,当我第一次检查时没有工作。我标记了另一个,因为对我来说看起来更干净。再次感谢
      【解决方案3】:

      您需要清除超时,以免它们触发。 http://jsfiddle.net/5G3BH/14/

      var timeoutHandler;
          $('.root li').mouseenter( function( e1 ) {
              var thisItem = $(this);
              clearTimeout(timeoutHandler);    
              timeoutHandler = setTimeout( function( e1 ) {
      
                  if ( $(thisItem).children().hasClass('open') ) { 
                      return; 
                  } else {
                      $(thisItem).children().addClass('open');
                      $(thisItem).siblings().children().removeClass('open');
                  } 
      
              }, 200 );
      
          }).mouseleave( function( e2 ) {
              var thisItem = $(this);
              clearTimeout(timeoutHandler);
              timeoutHandler = setTimeout( function( e2 ) {
                  if ( !$(thisItem).children().hasClass('open') ) { return; } else {                                  
                      $(thisItem).children().removeClass('open'); 
                  }
              }, 500 );
          }); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-25
        • 2012-03-04
        • 2012-03-19
        • 2011-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多