jQuery: code stops working after adding delay() and removeClass()

后端 未结 3 873
太阳男子
太阳男子 2020-12-11 11:27

Here\'s my code...

 $(\'nav ul li\').hover(function() {

    $(this).addClass(\'hoverIn\');


  },
  function() {

    $(this).addClass(\'hoverOut\');


  })         


        
相关标签:
3条回答
  • 2020-12-11 11:55

    .delay() only works with jQuery methods that use the animation queue, thus is does not work with removeClass().

    The removeClass() operation will still be performed, but it will be performed immediately, not after the delay time.

    So, when you do:

    $(this).addClass('hoverIn').delay(800).removeClass('hoverIn');
    

    that is the same as:

    $(this).addClass('hoverIn').removeClass('hoverIn');
    

    which is the same as doing nothing, thus you see not effect.


    You can solve your problem with setTimeout() like this:

     $('nav ul li').hover(function() {
        var self = $(this).addClass('hoverIn');
        setTimeout(function() {self.removeClass('hoverIn');}, 800);
      }, function() {
        var self = $(this).addClass('hoverOut');
        setTimeout(function() {self.removeClass('hoverOut');}, 800);
      });
    

    Or, using a common function, like this:

    jQuery.fn.addClassTemporary = function(cls, t) {
        var self = this.addClass(cls);
        setTimeout(function() {self.removeClass(cls);}, t);
    }
    
     $('nav ul li').hover(function() {
         $(this).addClassTemporary('hoverIn', 800);
     }, function() {
         $(this).addClassTemporary('hoverOut', 800);
     });
    
    0 讨论(0)
  • 2020-12-11 11:56

    jQuery .delay() applies to the animation queue, it does not serve as a timer like setTimeout does...

    To your goal, I can suggest you to use the hoverIntent plug-in:

    See this working Fiddle Example! adjust the timeout to fit your needs

    jQuery

    $("nav ul li").hoverIntent({    
        sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)    
        interval: 10,   // number = milliseconds for onMouseOver polling interval    
        timeout: 800,   // number = milliseconds delay before onMouseOut    
        over:function(){
            $(this).removeClass("hoverOut").toggleClass("hoverIn");
        },
        out: function(){
            $(this).removeClass("hoverIn").toggleClass("hoverOut");
        }
    });
    
    0 讨论(0)
  • 2020-12-11 12:04

    As others have mentioned, .removeClass() is not an animation function so is unaffected by any queued effects.

    The simplest solution is to use .queue() to insert your call into the animation queue:

    $(this).addClass('hoverIn').delay(800).queue(function() {
        $(this).removeClass('hoverIn').dequeue();
    });
    

    The .dequeue() call is important to ensure that any other queued operations still take place.

    Note that using the animation queue also means that you can use .stop() to cancel the operation if it hasn't happened yet. Using timers would make that a lot more complicated.


    If you want to get really fancy, this plugin I just knocked out will allow you to add any arbitrary jQuery function into the animation queue:

    (function($) {
        $.fn.queued = function() {
            var self = this;
            var func = arguments[0];
            var args = [].slice.call(arguments, 1);
            return this.queue(function() {
                $.fn[func].apply(self, args).dequeue();
            });
        }
    }(jQuery));
    

    with this, the line above would become:

    $(this).addClass('hoverIn').delay(800).queued('removeClass', 'hoverIn');
    

    demo at http://jsfiddle.net/alnitak/h5nWw/

    0 讨论(0)
提交回复
热议问题