我得到了这个基于 jQuery 的菜单,当您已经打开一个菜单并单击打开另一个菜单时,slideUp
和 slideDown
同时运行。看起来不太好!
是否可以让 slideDown
等待 slideUp
,这样它们就不会重叠?
我想这可能就像延迟 slideDown
的开始一样简单。但是,只有当已经打开需要先关闭的菜单时才会发生这种情况。如果没有什么需要关闭的,就不应该有任何延迟......
我对 js 了解不多,所以我不知道这有多复杂,甚至根本无法实现。
如果有任何帮助,我将不胜感激。 谢谢
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!');
}
})
最佳答案
是的,
$(".something").slideUp(500, function(){
// Callback, will work after 500ms of above animation will complete.
$(".somethingother").slideDown(500);
});
您的 jsfiddle js 代码非常困惑,所以我无法对其进行调整。
关于javascript - 基于 jQuery 的菜单 - 如何让 slideUp/Down 依次运行,而不是同时运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28547531/