1(function ($, window, undefined) { 2 // outside the scope of the jQuery plugin to 3 // keep track of all dropdowns 4 var $allDropdowns = $(); 5 6 // if instantlyCloseOthers is true, then it will instantly 7 // shut other nav items when a new one is hovered over 8 $.fn.dropdownHover = function (options) { 9 // don't do anything if touch is supported 10 // (plugin causes some issues on mobile) 11 if('ontouchstart' in document) return this; // don't want to affect chaining 12 13 // the element we really care about 14 // is the dropdown-toggle's parent 15 $allDropdowns = $allDropdowns.add(this.parent()); 16 17 return this.each(function () { 18 var $this = $(this), 19 $parent = $this.parent(), 20 defaults = { 21 delay: 0, 22 hoverDelay: 0, 23 instantlyCloseOthers: true 24 }, 25 data = { 26 delay: $(this).data('delay'), 27 hoverDelay: $(this).data('hover-delay'), 28 instantlyCloseOthers: $(this).data('close-others') 29 }, 30 showEvent = 'show.bs.dropdown', 31 hideEvent = 'hide.bs.dropdown', 32 // shownEvent = 'shown.bs.dropdown', 33 // hiddenEvent = 'hidden.bs.dropdown', 34 settings = $.extend(true, {}, defaults, options, data), 35 timeout, timeoutHover; 36 37 $parent.hover(function (event) { 38 // so a neighbor can't open the dropdown 39 if(!$parent.hasClass('open') && !$this.is(event.target)) { 40 // stop this event, stop executing any code 41 // in this callback but continue to propagate 42 return true; 43 } 44 45 if ($(window).width() > 767) 46 openDropdown(event); 47 }, function () { 48 if ($(window).width() > 767) { 49 // clear timer for hover event 50 window.clearTimeout(timeoutHover); 51 timeout = window.setTimeout(function () { 52 $this.attr('aria-expanded', 'false'); 53 $parent.removeClass('open'); 54 $this.trigger(hideEvent); 55 }, settings.delay); } 56 }); 57 58 // this helps with button groups! 59 $this.hover(function (event) { 60 // this helps prevent a double event from firing. 61 // see https://github.com/CWSpear/bootstrap-hover-dropdown/issues/55 62 if(!$parent.hasClass('open') && !$parent.is(event.target) && $(window).width() > 767) { 63 // stop this event, stop executing any code 64 // in this callback but continue to propagate 65 return true; 66 } 67 68 if ($(window).width() > 767) 69 openDropdown(event); 70 }); 71 72 // handle submenus 73 $parent.find('.dropdown-submenu').each(function (){ 74 var $this = $(this); 75 var subTimeout; 76 $this.hover(function () { 77 window.clearTimeout(subTimeout); 78 $this.children('.dropdown-menu').show(); 79 // always close submenu siblings instantly 80 $this.siblings().children('.dropdown-menu').hide(); 81 }, function () { 82 var $submenu = $this.children('.dropdown-menu'); 83 subTimeout = window.setTimeout(function () { 84 $submenu.hide(); 85 }, settings.delay); 86 }); 87 }); 88 89 function openDropdown(event) { 90 // clear dropdown timeout here so it doesnt close before it should 91 window.clearTimeout(timeout); 92 // restart hover timer 93 window.clearTimeout(timeoutHover); 94 95 // delay for hover event. 96 timeoutHover = window.setTimeout(function () { 97 $allDropdowns.find(':focus').blur(); 98 99 if(settings.instantlyCloseOthers === true) 100 $allDropdowns.removeClass('open'); 101 102 // clear timer for hover event 103 window.clearTimeout(timeoutHover); 104 $this.attr('aria-expanded', 'true'); 105 $parent.addClass('open'); 106 $this.trigger(showEvent); 107 }, settings.hoverDelay); 108 } 109 }); 110 }; 111 112 $(document).ready(function () { 113 // apply dropdownHover to all elements with the data-hover="dropdown" attribute 114 $('[data-hover="dropdown"]').dropdownHover(); 115 }); 116})(jQuery, window);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.