/*! * Dropdownhover v1.0.0 (http://bs-dropdownhover.kybarg.com) */ +function ($) { 'use strict'; // DROPDOWNHOVER CLASS DEFINITION // ========================= var Dropdownhover = function (element, options) { this.options = options this.$element = $(element) var that = this // Defining if navigation tree or single dropdown this.dropdowns = this.$element.hasClass('dropdown-toggle') ? this.$element.parent().find('.dropdown-menu').parent('.dropdown') : this.$element.find('.dropdown') this.dropdowns.each(function(){ $(this).on('mouseenter.bs.dropdownhover', function(e) { that.show($(this).children('a, button')) }) }) this.dropdowns.each(function(){ $(this).on('mouseleave.bs.dropdownhover', function(e) { that.hide($(this).children('a, button')) }) }) } Dropdownhover.TRANSITION_DURATION = 300 Dropdownhover.DELAY = 150 Dropdownhover.TIMEOUT Dropdownhover.DEFAULTS = { animations : ['fadeInDown', 'fadeInRight', 'fadeInUp', 'fadeInLeft'], } // Opens dropdown menu when mouse is over the trigger element Dropdownhover.prototype.show = function (_dropdownLink) { var $this = $(_dropdownLink) window.clearTimeout(Dropdownhover.TIMEOUT) // Close all dropdowns $('.dropdown').not($this.parents()).each(function(){ $(this).removeClass('show'); $(this).children('.dropdown-menu').removeClass('show'); }); var effect = this.options.animations[0] if ($this.is('.disabled, :disabled')) return var $parent = $this.parent() var isActive = $parent.hasClass('show') if (!isActive) { var $dropdown = $this.next('.dropdown-menu') var relatedTarget = { relatedTarget: this } $parent.addClass('show') $parent.children('.dropdown-menu').addClass('show') var side = this.position($dropdown) side == 'top' ? effect = this.options.animations[2] : side == 'right' ? effect = this.options.animations[3] : side == 'left' ? effect = this.options.animations[1] : effect = this.options.animations[0] $dropdown.addClass('animated ' + effect) var transition = $.support.transition && $dropdown.hasClass('animated') transition ? $dropdown .one('bsTransitionEnd', function () { $dropdown.removeClass('animated ' + effect) }) .emulateTransitionEnd(Dropdownhover.TRANSITION_DURATION) : $dropdown.removeClass('animated ' + effect) } return false } // Closes dropdown menu when moise is out of it Dropdownhover.prototype.hide = function (_dropdownLink) { var that = this var $this = $(_dropdownLink) var $parent = $this.parent() Dropdownhover.TIMEOUT = window.setTimeout(function () { $parent.removeClass('show') $parent.children('.dropdown-menu').removeClass('show') }, Dropdownhover.DELAY) } // Calculating position of dropdown menu Dropdownhover.prototype.position = function (dropdown) { var win = $(window); // Reset css to prevent incorrect position dropdown.css({ bottom: '', left: '', top: '', right: '' }).removeClass('dropdownhover-top') var viewport = { top : win.scrollTop(), left : win.scrollLeft() }; viewport.right = viewport.left + win.width(); viewport.bottom = viewport.top + win.height(); var bounds = dropdown.offset(); bounds.right = bounds.left + dropdown.outerWidth(); bounds.bottom = bounds.top + dropdown.outerHeight(); var position = dropdown.position(); position.right = bounds.left + dropdown.outerWidth(); position.bottom = bounds.top + dropdown.outerHeight(); var side = '' var isSubnow = dropdown.parents('.dropdown-menu').length if(isSubnow) { if (position.left < 0) { side = 'left' dropdown.removeClass('dropdownhover-right').addClass('dropdownhover-left') } else { side = 'right' dropdown.addClass('dropdownhover-right').removeClass('dropdownhover-left') } if (bounds.left < viewport.left) { side = 'right' dropdown.css({ left: '100%', right: 'auto' }).addClass('dropdownhover-right').removeClass('dropdownhover-left') } else if (bounds.right > viewport.right) { side = 'left' dropdown.css({ left: 'auto', right: '100%' }).removeClass('dropdownhover-right').addClass('dropdownhover-left') } if (bounds.bottom > viewport.bottom) { dropdown.css({ bottom: 'auto', top: -(bounds.bottom-viewport.bottom) }) } else if (bounds.top < viewport.top) { dropdown.css({ bottom: -(viewport.top-bounds.top), top: 'auto' }) } } else { // Defines special position styles for root dropdown menu var parentLi = dropdown.parent('.dropdown') var pBounds = parentLi.offset() pBounds.right = pBounds.left + parentLi.outerWidth() pBounds.bottom = pBounds.top + parentLi.outerHeight() if (bounds.right > viewport.right) { dropdown.css({ left: -(bounds.right-viewport.right), right: 'auto' }) } if (bounds.bottom > viewport.bottom && (pBounds.top - viewport.top) > (viewport.bottom - pBounds.bottom) || dropdown.position().top < 0) { side = 'top' dropdown.css({ bottom: '100%', top: 'auto' }).addClass('dropdownhover-top').removeClass('dropdownhover-bottom') } else { side = 'bottom' dropdown.addClass('dropdownhover-bottom') } } return side; } // DROPDOWNHOVER PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.dropdownhover') var settings = $this.data() if($this.data('animations') !== undefined && $this.data('animations') !== null) settings.animations = $.isArray(settings.animations) ? settings.animations : settings.animations.split(' ') var options = $.extend({}, Dropdownhover.DEFAULTS, settings, typeof option == 'object' && option) if (!data) $this.data('bs.dropdownhover', (data = new Dropdownhover(this, options))) }) } var old = $.fn.dropdownhover $.fn.dropdownhover = Plugin $.fn.dropdownhover.Constructor = Dropdownhover // DROPDOWNHOVER NO CONFLICT // ==================== $.fn.dropdownhover.noConflict = function () { $.fn.dropdownhover = old return this } // APPLY TO STANDARD DROPDOWNHOVER ELEMENTS // =================================== var resizeTimer; $(document).ready(function () { if($(window).width() >= 768) { // Breakpoin plugin is activated (768px) $('[data-hover="dropdown"]').each(function () { var $target = $(this) Plugin.call($target, $target.data()) }) } }) $(window).on('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function(){ if($(window).width() >= 768) // Breakpoin plugin is activated (768px) $('[data-hover="dropdown"]').each(function () { var $target = $(this) Plugin.call($target, $target.data()) }) else // Disabling and clearing plugin data if screen is less 768px $('[data-hover="dropdown"]').each(function () { $(this).removeData('bs.dropdownhover') if($(this).hasClass('dropdown-toggle')) $(this).parent('.dropdown').find('.dropdown').andSelf().off('mouseenter.bs.dropdownhover mouseleave.bs.dropdownhover') else $(this).find('.dropdown').off('mouseenter.bs.dropdownhover mouseleave.bs.dropdownhover') }) }, 200) }) }(jQuery);