twbs / bootstrap

The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.
https://getbootstrap.com
MIT License
170.48k stars 78.83k forks source link

Dropdown closing on mousedown instead of mouseup #21941

Closed miguelmich closed 7 years ago

miguelmich commented 7 years ago

I noticed in the last release (v4.0.0-alpha.6) a new dropdown behavior was introduced, my question is: is this new behavior intentional? because the new interaction seems to be a little odd compared with the old one (closing dropdowns on mouseup).

Testing on Google Chrome Version 55.0.2883.87 (64-bit), Linux Ubuntu Gnome

Thanks in advance

patrickhlauke commented 7 years ago

can't reproduce this (in Windows anyway). dropdowns on http://v4-alpha.getbootstrap.com/components/dropdowns/ all open on mouseup, not mousedown

miguelmich commented 7 years ago

Oh ok, my mistake, I'm going to edit the issue, the problem is the dropdown is closing on mousedown.

patrickhlauke commented 7 years ago

again, can't reproduce the issue on closing either (assuming you mean clicking the button with the down-triangle icon again to close the dropdown)

miguelmich commented 7 years ago

In this screencast you can see how the dropdown closes on mousedown instead of mouseup

ezgif com-2f46ff81e9

That was recorded using: http://v4-alpha.getbootstrap.com/components/dropdowns/

miguelmich commented 7 years ago

This current behavior is causing for example in mobile resolutions (where you probably have a main navbar) the opening of siblings dropdowns almost impossible if you comes from an opened dropdown: ezgif com-8011d50848

patrickhlauke commented 7 years ago

Thanks, that clarifies the problem more. Confirmed

pvdlg commented 7 years ago

This is a regression due to #21375. Following #21375, menu is now closed on both click and focusin event when they happen outside the dropdown. When you have a menu open and click on another dropdown trigger:

This is what give the impression that the menu is closed on mousedown.

In order to fix this issue and the one solved in #21375 I updated my PR #21535 (as I need improvement from this PR for a proper fix). With #21535, the menu is not closed on focusin anymore but when using the tab key to focus outside the menu, therefore achieving the fix intended in #21375 and avoiding the current regression.

Once #21535 is merge the problem will be fixed.

719media commented 7 years ago

I noticed a related issue when using a dropdown with checkbox inputs inside of a modal. Perhaps this PR will also address this issue as I understand the "focusin" event is no longer used for toggling, so I think that labels which switch the focus will no longer close the dropdown?? Not sure.

See here:

https://jsfiddle.net/32nupfrc/6/

pvdlg commented 7 years ago

@719media, it seems there is two issues mentioned in your JSFiddle:

1/ When clicking on a dropdown-item containing a checkbox the menu is closed.

The content of a dropdown-item is not handled by the plugin. No matter what you have inside dropdown-item clicking on it will close the menu. The PR #21535 will not change that.

2/ If the dropdown is in a modal and you click on the label of the dropdown-item it doesn't toggle the checkbox

I'm not totally sure why it happens... It seems to related to an interaction between the focus handling of the modal component and the dropdown listening on focusin to close the menu. It seems that #21535 fix this second issue (even though I'm not entirely sure why): https://jsfiddle.net/to6281b4/

That said, I'm not sure that the case of a checkbox, within a dropdown, within a modal is something that was planned to be handled by Bootstrap... At least I'm pretty sure it's not a case that is tested for non-regression.

kerolol commented 7 years ago

Any idea when this will be merged? Is there a way to use a hack or something for a temporary solution?

kimemax commented 7 years ago

I discovered this 2 dropdown issue yesterday and tested that it works as expected in BS3 but not in BS4 v4.0.0-Alpha.6 and since i didn't find any matches on Google incl. this github issue i made a note of it on StackOverflow: http://stackoverflow.com/questions/42680429/boostrap4-issue-with-two-dropdown-in-burgermenu JSFiddle: https://jsfiddle.net/kimemax/dg2375bb/1/ Looking forward to the fix.

mstred commented 7 years ago

@kerolol, a bit nasty (and late) but... maybe handling <label> element click event and applying event.stopPropagation() on it should be something. Been there, done that (v3.3.x, btw). 😞

marcusguttenplan commented 7 years ago

I just ran into this issue today after starting refactor to b4v6 a few days ago, having the exact same behavior as @miguelmich and @kimemax. Has a solution been merged yet? Didn't see anything relevant in @vanduynslagerp's diffs. It seems that clicking the next neighbor of an open dropdown closes the dropdown entirely, but clicking a previous neighbor has intended behavior. I have tried EVERYTHING, wondering if maybe my fumbling can inspire a hack.

Using jquery, first tried to if statement any instance of .show on a dropdown, remove that .show and then add it to the target of the click. When that didn't work, tried to remove .show from the previous neighbor, tried to target aria-expanded="true", tried to remove focus with blur, as well as entirely stopPropagation() preventDefault() and unbind().

Anyone have any idea as to a better logic than my bad attempts? It feels like it should be easy, but it hasn't been.

marcusguttenplan commented 7 years ago

So, super hacky with some cheesy jquery animation, but this logic works for me:

$('.dropdown').click(function() {

        var dropdownHide = this;
        if ($('.dropdown-menu', this).is(':visible')) {
            $('.dropdown-menu', this).slideUp(function() {
                $(dropdownHide).removeClass('open');
            });
        }
        else {
            var neighbors = $(this).next().add($(this).prev());
            $('.dropdown-menu').slideUp();
            neighbors.children('.dropdown-menu').slideUp();
            $('.dropdown-menu', this).slideDown();
            $(dropdownHide).addClass('open');
        }
    });

Credit due to this great jsfiddle!

Curious to know what a bootstrappy solution would be, but this works for now.