Skip to content

fix(dropdown): use mousedown to close dropdown #1815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed

fix(dropdown): use mousedown to close dropdown #1815

wants to merge 17 commits into from

Conversation

rinick
Copy link
Contributor

@rinick rinick commented May 11, 2018

dropdown wont close when event gets stopPropagation()
since click event stopPropagation() is used in several componenets in bootstrap-vue, it's better to switch to mousedown event to close popup.
resolves #1814

besides that, clickout listener is now only added on demand, resolves #1817

@codecov
Copy link

codecov bot commented May 11, 2018

Codecov Report

Merging #1815 into dev will increase coverage by 0.45%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev    #1815      +/-   ##
==========================================
+ Coverage   64.77%   65.23%   +0.45%     
==========================================
  Files         156      156              
  Lines        2950     2957       +7     
  Branches      810      812       +2     
==========================================
+ Hits         1911     1929      +18     
+ Misses        752      745       -7     
+ Partials      287      283       -4
Impacted Files Coverage Δ
src/mixins/dropdown.js 10.71% <0%> (+3.57%) ⬆️
src/mixins/clickout.js 100% <100%> (+28.57%) ⬆️
src/mixins/listen-on-root.js 100% <0%> (+33.33%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 24d53d7...9de4a43. Read the comment docs.

@tmorehouse
Copy link
Member

tmorehouse commented Oct 23, 2018

@rinick. Note multiple components use the clickoutListener.

Have you ensured that this change does not impact other components?

@tmorehouse
Copy link
Member

There are also a few conflicts with the test fixture HTML (and indirectly with the fixture test script).

Could you also adjust your test HTML and JavaScript?

@tmorehouse
Copy link
Member

And would you be able to merge the latest dev into your repo? There are a few conflicts from recent changes in dropdown test fixtures.

if (!this._clickOutElement && typeof document !== 'undefined') {
this._clickOutElement = document.documentElement
this._clickOutElement.addEventListener('mousedown', this._clickOutListener)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adding an event listener, if the event handler is already attached, reattaching it will not actually rea attach it (as long as the function reference is the same as the one that was called).

So storing the document element on the component is not necessary.

A simple check for the existence of typeof document !== 'undefined' is needed, then either add or remove the listener when needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use the eventOn and eventOff functions from utils/dom.js to add and remove the events (this would help with code minification)

just add import { eventOn, eventOff } from '../utils/dom at the top, and then:

eventOn(document.documentElement, 'mousedown', this._this._clickOutListener)
eventOff(document.documentElement, 'mousedown', this._this._clickOutListener)

}
},
methods: {
listenClickOut () {
if (!this._clickOutElement && typeof document !== 'undefined') {
this._clickOutElement = document.documentElement
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why store a reference of the document element on the component instance?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could store a reference to the document element in a constant at the top of the mixin

const docEl = document ? document.documentElement : null

and then use the following:

  beforeDestroy() {
    if (docEl) {
        eventOff(docEl, 'mousedown', this._clickoutListener)
    }
    if (this.clickOutListener) {
      this.clickOutListener()
    }
  },
  methods: {
    listenClickOut () {
      if (docEl) {
        eventOn(docEl, 'mousedown', this._clickoutListener)
      }
    }
  }

@tmorehouse
Copy link
Member

Closing as PR #2159 fixes the issues wrt clickout listener.

@tmorehouse tmorehouse closed this Nov 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

clickout.js need some optimization dropdown wont close when click on component that uses stopPropagation
2 participants