【问题标题】:jQuery based menu - How to make slideUp/Down run one after the other, not simultaneously?基于 jQuery 的菜单 - 如何让 slideUp/Down 一个接一个地运行,而不是同时运行?
【发布时间】:2015-02-17 02:19:43
【问题描述】:

我得到了这个基于 jQuery 的菜单,只要您已经打开了一个菜单并单击打开另一个菜单,slideUpslideDown 就会同时运行。不好看!

是否可以让slideDown 等待slideUp,使它们不重叠?

我想这可能就像延迟slideDown 的启动一样简单。但是,只有在已经打开需要先关闭的菜单时才会发生这种情况。如果什么都不需要关闭,就不应该有任何延迟......

我对 js 了解不多,所以我不知道这有多复杂,甚至完全不知道。

如果有任何帮助,我将不胜感激。 谢谢

JSFiddle

JS:

(function() {
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    __slice = [].slice;

  (function($, window) {
    var Tendina;
    Tendina = (function() {
      Tendina.prototype.defaults = {
        animate: true,
        speed: 500,
        onHover: false,
        hoverDelay: 200,
        activeMenu: null
      };

      function Tendina(el, options) {
        this._eventHandler = __bind(this._eventHandler, this);
        this.options = $.extend({}, this.defaults, options);
        this.$el = $(el);
        this.elSelector = this._getSelector(this.$el);
        this.$el.addClass('tendina');
        this.linkSelector = "" + this.elSelector + " a";
        this.$listElements = $(this.linkSelector).parent('li');
        this._hideSubmenus();
        this.mouseEvent = this.options.onHover === true ? 'mouseenter.tendina' : 'click.tendina';
        this._bindEvents();
        if (this.options.activeMenu !== null) {
          this._openActiveMenu(this.options.activeMenu);
        }
      }

      Tendina.prototype._bindEvents = function() {
        return $(document).on(this.mouseEvent, this.linkSelector, this._eventHandler);
      };

      Tendina.prototype._unbindEvents = function() {
        return $(document).off(this.mouseEvent);
      };

      Tendina.prototype._getSelector = function(el) {
        var elId, firstClass, _ref;
        firstClass = (_ref = $(el).attr('class')) != null ? _ref.split(' ')[0] : void 0;
        elId = $(el).attr('id');
        if (elId !== void 0) {
          return "#" + elId;
        } else {
          return "." + firstClass;
        }
      };

      Tendina.prototype._isFirstLevel = function(targetEl) {
        if ($(targetEl).parent().parent().hasClass('tendina')) {
          return true;
        }
      };

      Tendina.prototype._eventHandler = function(event) {
        var targetEl;
        targetEl = event.currentTarget;
        if (this._hasChildrenAndIsHidden(targetEl)) {
          event.preventDefault();
          if (this.options.onHover) {
            return setTimeout((function(_this) {
              return function() {
                if ($(targetEl).is(':hover')) {
                  return _this._openSubmenu(targetEl);
                }
              };
            })(this), this.options.hoverDelay);
          } else {
            return this._openSubmenu(targetEl);
          }
        } else if (this._isCurrentlyOpen(targetEl)) {
      event.preventDefault();
      if (!this.options.onHover) {
        return this._closeSubmenu(targetEl);
      }
    }
  };

  Tendina.prototype._openSubmenu = function(el) {
    var $openMenus, $targetMenu;
    $targetMenu = $(el).next('ul');
    $openMenus = this.$el.find('> .selected ul').not($targetMenu).not($targetMenu.parents('ul'));
    $(el).parent('li').addClass('selected');
    this._close($openMenus);
    this.$el.find('.selected').not($targetMenu.parents('li')).removeClass('selected');
    this._open($targetMenu);
    if (this.options.openCallback) {
      return this.options.openCallback($(el).parent());
    }
  };

  Tendina.prototype._closeSubmenu = function(el) {
    var $nestedMenus, $targetMenu;
    $targetMenu = $(el).next('ul');
    $nestedMenus = $targetMenu.find('li.selected');
    $(el).parent().removeClass('selected');
    this._close($targetMenu);
    $nestedMenus.removeClass('selected');
    this._close($nestedMenus.find('ul'));
    if (this.options.closeCallback) {
      return this.options.closeCallback($(el).parent());
    }
  };

  Tendina.prototype._open = function($el) {
    if (this.options.animate) {
      return $el.stop(true, true).slideDown(this.options.speed);
    } else {
      return $el.show();
    }
  };

  Tendina.prototype._close = function($el) {
    if (this.options.animate) {
      return $el.stop(true, true).slideUp(this.options.speed);
    } else {
      return $el.hide();
    }
  };

  Tendina.prototype._hasChildrenAndIsHidden = function(el) {
    return $(el).next('ul').length > 0 && $(el).next('ul').is(':hidden');
  };

  Tendina.prototype._isCurrentlyOpen = function(el) {
    return $(el).parent().hasClass('selected');
  };

  Tendina.prototype._hideSubmenus = function() {
    return this.$el.find('ul').hide();
  };

  Tendina.prototype._showSubmenus = function() {
    this.$el.find('ul').show();
    return this.$el.find('li').addClass('selected');
  };

  Tendina.prototype._openActiveMenu = function(element) {
    var $activeMenu, $activeParents;
    $activeMenu = element instanceof jQuery ? element : this.$el.find(element);
    $activeParents = $activeMenu.closest('ul').parents('li').find('> a');
    if (this._hasChildrenAndIsHidden($activeParents)) {
      $activeParents.next('ul').show();
    } else {
      $activeMenu.next('ul').show();
    }
    $activeMenu.parent().addClass('selected');
    return $activeParents.parent().addClass('selected');
  };

  Tendina.prototype.destroy = function() {
    this.$el.removeData('tendina');
    this._unbindEvents();
    this._showSubmenus();
    this.$el.removeClass('tendina');
    return this.$el.find('.selected').removeClass('selected');
  };

  Tendina.prototype.hideAll = function() {
    return this._hideSubmenus();
  };

  Tendina.prototype.showAll = function() {
    return this._showSubmenus();
  };

  return Tendina;

})();
return $.fn.extend({
  tendina: function() {
    var args, option;
    option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    return this.each(function() {
      var $this, data;
      $this = $(this);
      data = $this.data('tendina');
      if (!data) {
        $this.data('tendina', (data = new Tendina(this, option)));
      }
      if (typeof option === 'string') {
        return data[option].apply(data, args);
      }
    });
  }
});
  })(window.jQuery, window);

}).call(this);


$('.dropdown').tendina({
        // This is a setup made only
        // to show which options you can use,
        // it doesn't actually make sense!
        animate: true,
        speed: 500,
        onHover: false,
        hoverDelay: 300,
        activeMenu: $('#deepest'),
        openCallback: function(clickedEl) {
          console.log('Hey dude!');
        },
        closeCallback: function(clickedEl) {
          console.log('Bye dude!');
        }
      })

【问题讨论】:

    标签: javascript jquery html css menu


    【解决方案1】:

    是的,

    $(".something").slideUp(500, function(){
    
       // Callback, will work after 500ms of above animation will complete.
       $(".somethingother").slideDown(500);
    
    });
    

    您的 jsfiddle js 代码非常混乱,所以我无法调整。

    【讨论】:

    • 这怎么行?你确定你明白我要解决的问题吗? slideUp/Down 效果很好......我只是想在已经打开菜单并且需要先运行 slideUp 时延迟 slideDown。目前它们正在同时运行......这就是问题所在!
    • 对不起,我无意中使用了缩小版。这是一个正确的小提琴:jsfiddle.net/vf7adn54/7很容易理解。
    • 是的,当$(".something").slideUp(500)完成slideUp效果时,上面的代码会做$(".somethingother").slideDown(500)
    • 如果它解决了您的问题,请考虑投票并将其标记为正确答案。
    • 您介意将它添加到这个 jsfiddle jsfiddle.net/vf7adn54/7 吗?我是 js 自学成才,不知道如何处理它......谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2010-09-09
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多