xbase-2.x-dev/js/libraries/jquery.hovermenu.js
js/libraries/jquery.hovermenu.js
/**
* jQuery Hover Menu.
* Touch friendly dropdown menu.
*/
;( function($, window, document, undefined) {
'use strict';
var pluginName = 'hoverMenu';
var defaults = {
hoverClass: 'hover',
itemsSelector: 'li',
linksSelector: 'li > a',
debug: false,
};
function Plugin (element, options) {
this.element = element;
this.$element = $(element);
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
$.extend(Plugin.prototype, {
init: function() {
var plugin = this;
var $element = plugin.$element;
var settings = plugin.settings;
var $menuItems = $element.find(settings.itemsSelector);
var $menuLinks = $element.find(settings.linksSelector);
var linkLongTapTimer;
// Emulate hover on non-touch devices
$menuItems.on('mouseenter.hovermenu', function (event) {
plugin.log('Item mouseenter event');
plugin.log('Add class to hovered item', this);
$(this).addClass(settings.hoverClass);
});
$menuItems.on('mouseleave.hovermenu', function (event) {
plugin.log('Item mouseleave event');
plugin.log('Remove class from hovered item', this);
$(this).removeClass(settings.hoverClass);
});
// Emulate hover on touch devices
$menuItems.on('touchend.hovermenu', function (event) {
plugin.log('Item touchend event', this);
var $clickedMenuItem = $(this);
// Add class
if (!$clickedMenuItem.hasClass(settings.hoverClass)) {
// Remove class from other items
plugin.log('Remove class from other items');
$menuItems.each(function () {
var $menuItem = $(this);
if (!$.contains($menuItem[0], $clickedMenuItem[0]) && $menuItem.hasClass(settings.hoverClass)) {
plugin.log($menuItem[0]);
$menuItem.removeClass(settings.hoverClass);
}
});
plugin.log('Add class to clicked item', $clickedMenuItem[0]);
$clickedMenuItem.addClass(settings.hoverClass);
}
// Remove class
else {
plugin.log('Remove class from clicked item', $clickedMenuItem[0]);
$clickedMenuItem.removeClass(settings.hoverClass);
}
plugin.log('Link touchend stopPropagation', this);
event.stopPropagation();
});
// Prevents goto link url
$menuLinks.on('touchend.hovermenu', function (event) {
plugin.log('Link touchend event', this);
event.preventDefault();
plugin.log('Clear linkLongTapTimer');
clearTimeout(linkLongTapTimer);
});
// Goto link url on long tap
$menuLinks.on('touchstart.hovermenu', function (event) {
plugin.log('Link touchstart event', this);
var $menuLink = $(this);
plugin.log('Create linkLongTapTimer');
linkLongTapTimer = setTimeout(function () {
window.location = $menuLink.attr('href');
}, 400);
});
// Disable link context menu
$menuLinks.on('contextmenu.hovermenu', function (event) {
plugin.log('Link contextmenu event', this);
event.preventDefault();
});
},
destroy: function () {
var plugin = this;
var $element = plugin.$element;
var settings = plugin.settings;
var $menuItems = $element.find(settings.itemsSelector);
var $menuLinks = $element.find(settings.linksSelector);
$menuItems.off('.hovermenu');
$menuLinks.off('.hovermenu');
},
log: function () {
if (this.settings.debug) {
console.log.apply(this, arguments);
}
}
});
$.fn[pluginName] = function(options) {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
return $.data(this, 'plugin_' + pluginName);
};
})(jQuery, window, document);
