|
3 | 3 | * Project: Bootstrap Hover Dropdown
|
4 | 4 | * Author: Cameron Spear
|
5 | 5 | * Version: v2.1.3
|
6 |
| - * Contributors: Mattia Larentis |
7 | 6 | * Dependencies: Bootstrap's Dropdown plugin, jQuery
|
8 | 7 | * Description: A simple plugin to enable Bootstrap dropdowns to active on hover and provide a nice user experience.
|
9 | 8 | * License: MIT
|
|
17 | 16 | // if instantlyCloseOthers is true, then it will instantly
|
18 | 17 | // shut other nav items when a new one is hovered over
|
19 | 18 | $.fn.dropdownHover = function (options) {
|
20 |
| - // don't do anything if touch is supported |
21 |
| - // (plugin causes some issues on mobile) |
22 |
| - if('ontouchstart' in document) return this; // don't want to affect chaining |
| 19 | + // this disabled touch actions on the elements so we can hook into Pointer Events |
| 20 | + this.attr('touch-action', 'pan-y'); |
23 | 21 |
|
24 | 22 | // the element we really care about
|
25 | 23 | // is the dropdown-toggle's parent
|
|
45 | 43 | settings = $.extend(true, {}, defaults, options, data),
|
46 | 44 | timeout, timeoutHover;
|
47 | 45 |
|
48 |
| - $parent.hover(function (event) { |
| 46 | + $parent.on('pointerenter', function (event) { |
| 47 | + if (isPointerTouchEvent(event)) return; |
49 | 48 | // so a neighbor can't open the dropdown
|
50 | 49 | if(!$parent.hasClass('open') && !$this.is(event.target)) {
|
51 | 50 | // stop this event, stop executing any code
|
|
54 | 53 | }
|
55 | 54 |
|
56 | 55 | openDropdown(event);
|
57 |
| - }, function () { |
| 56 | + }).on('pointerleave', function (event) { |
| 57 | + if (isPointerTouchEvent(event)) return; |
58 | 58 | // clear timer for hover event
|
59 |
| - window.clearTimeout(timeoutHover) |
| 59 | + window.clearTimeout(timeoutHover); |
60 | 60 | timeout = window.setTimeout(function () {
|
61 | 61 | $this.attr('aria-expanded', 'false');
|
62 | 62 | $parent.removeClass('open');
|
|
65 | 65 | });
|
66 | 66 |
|
67 | 67 | // this helps with button groups!
|
68 |
| - $this.hover(function (event) { |
| 68 | + $this.on('pointerenter', function (event) { |
| 69 | + if (isPointerTouchEvent(event)) return; |
69 | 70 | // this helps prevent a double event from firing.
|
70 | 71 | // see https://github.com/CWSpear/bootstrap-hover-dropdown/issues/55
|
71 | 72 | if(!$parent.hasClass('open') && !$parent.is(event.target)) {
|
|
81 | 82 | $parent.find('.dropdown-submenu').each(function (){
|
82 | 83 | var $this = $(this);
|
83 | 84 | var subTimeout;
|
84 |
| - $this.hover(function () { |
| 85 | + $this.on('pointerenter', function (event) { |
| 86 | + if (isPointerTouchEvent(event)) return; |
85 | 87 | window.clearTimeout(subTimeout);
|
86 | 88 | $this.children('.dropdown-menu').show();
|
87 | 89 | // always close submenu siblings instantly
|
88 | 90 | $this.siblings().children('.dropdown-menu').hide();
|
89 |
| - }, function () { |
| 91 | + }).on('pointerleave', function (event) { |
| 92 | + if (isPointerTouchEvent(event)) return; |
90 | 93 | var $submenu = $this.children('.dropdown-menu');
|
91 | 94 | subTimeout = window.setTimeout(function () {
|
92 | 95 | $submenu.hide();
|
|
104 | 107 | timeoutHover = window.setTimeout(function () {
|
105 | 108 | $allDropdowns.find(':focus').blur();
|
106 | 109 |
|
107 |
| - if(settings.instantlyCloseOthers === true) |
| 110 | + if(settings.instantlyCloseOthers === true) { |
108 | 111 | $allDropdowns.removeClass('open');
|
| 112 | + } |
109 | 113 |
|
110 | 114 | // clear timer for hover event
|
111 | 115 | window.clearTimeout(timeoutHover);
|
|
114 | 118 | $this.trigger(showEvent);
|
115 | 119 | }, settings.hoverDelay);
|
116 | 120 | }
|
| 121 | + |
| 122 | + function isPointerTouchEvent(event) { |
| 123 | + // need to get the originalEvent if jQuery was used to bind the event |
| 124 | + event = event.originalEvent || event; |
| 125 | + // I'm not sure we need to check for falsey pointerTypes or if it will cause issues... |
| 126 | + // In my testing, I found it sometimes be empty when I expected touch, but it was inconsistent |
| 127 | + return !event.pointerType || event.pointerType === 'touch'; |
| 128 | + } |
117 | 129 | });
|
118 | 130 | };
|
119 | 131 |
|
|
0 commit comments