vue-bulma / click-outside Goto Github PK
View Code? Open in Web Editor NEWClickOutside directive for Vue.
License: MIT License
ClickOutside directive for Vue.
License: MIT License
[Vue warn]: Error in directive click-outside bind hook: "TypeError: Cannot read property '$isServer' of undefined"
version 1.0.6
I'm using a datepicker component (from Vuetify) with this library and it works mostly as expected; I click outside of the component, the event is fired; I click inside it, and nothing happens. However, when I click a date in de datepicker, which is a <button>
, the outside-click event is fired.
某些情况下,需要暂时取消click-ouside功能,如何设置?
For now, the directive can be installed just as a directive. But it would be better to export as a Vue plugin with install
function that would register a directive globally. Just like this:
export default {
install (Vue, options) {
Vue.directive('vue-click-outside', {
bind () { ... all the logic here ... }
}
}
}
And later on, bundle for different formats. It would any person use the directive in any format they want. But for now... Looks like I have to migrate for another click-outside.
Missing support for Server Side Rendering: invoking document.addEventListener('click', handler)
doesn't work at server-side.
The latest merge added the ES6 "const" keyword to the code. This caused our builds to fail. Was this intended? Maybe you could provide an ES5 compatible .min file via npm.
Thanks!
I have a sidebar panel, that gets rendered when a button is clicked in a div (v-if).
When a user clicks outside this panel, the panel should close itself.
This is ok, but, the v-outside-click is being triggered along the button click that allows the panel to be rendered in the first place. The result is that the panel is not rendered at all, or is hidden in the same instant that is enabled.
I tried an alternative to this package "v-on-click-outside" and it does not have this issue, but it will be nice to have this corrected it here.
背景:select(element-ui里的)不是要点击的元素
现象:点击select,没有走到对应的回调函数里面
I was facing an issue where if any sort of data changed, it would trigger the update method of the directive.
Navigating away from the page and subsequent clicks would still fire the click event and then error. The click event wasn't unset.
I tried to figure out why. When the handler is set el.__vueClickOutside__
will contain something like handler(e)
which is great. That's what we want to see. The value of el.__vueClickOutside__
was boundFn(a)
inside of the unbind method which is the reason why it would not unbind the event. I checked binding.value
within the update method to see that it is the update method that is setting el.__vueClickOutside__
to boundFn(a)
. This leaves me to believe the update method sets a "clone" of the handler and there for not being unset as the original binding is a different function.
It would be great if someone could duplicate this issue. The steps are simple.
Have an element that uses vue-click-outside
and make sure your data changes which causes the view to update. Navigate away from the page (I use vue-router
so I don't refresh the app) and it will be fine. This is because it was handled. Click anywhere on the page or navigate to another and so on, will result in an error as follows:
Uncaught TypeError: Failed to execute 'contains' on 'Node': parameter 1 is not of type 'Node'.
at isPopup (app.js:8421)
at HTMLDocument.handler (app.js:8442)
This is because the node in question no longer exists but the event is still set. Hopefully I made sense.
vue.esm.js?a026:628 [Vue warn]: Error in directive click-outside unbind hook: "TypeError: Cannot read property 'handler' of undefined"
vue.esm.js?a026:1897 TypeError: Cannot read property 'handler' of undefined
at unbind (index.js?e67d:65)
at callHook$1 (vue.esm.js?a026:6685)
at _update (vue.esm.js?a026:6646)
!isServer(vNode) && document.removeEventListener('click', el.vueClickOutside.handler)
I am currently on a project and i wanted to use this plugin but not working
I noticed that the handle function is triggered at the event bubble stage.However, it would not be triggered when the click event handle by the function with 'event.stopPropagation()'.So, I think trigger the handle at the event capture will be better.
Hey, thanks for the great starter kit. You can replace this directive https://jsfiddle.net/Linusborg/Lx49LaL8/ to be 2.0 ready.
Hi, with this plugin we can capture outside events, but cannot prevent it like event.preventDefault
Is it possible in vue.js way ?
When I LMB on some element and drag mouse outside, the event fires.
It can be a problem when the element is a dialog window and a user is trying to select some text with mouse and drags it too far away.
Maybe I did something wrong, but it looks like an issue.
It needs to be updated. I actually tried it on modals, dropdowns, and various other elements. The problem is, it does not work properly on elements that were not on the page and appear in occasions and conditions such as modals or dropdowns.
For anyone looking for solutions,
I recommend vueuse/onClickOutside:
https://vueuse.org/core/onClickOutside/
I noticed that this does not work in IE11, so I made some changes to make it work in IE11 too.
Here is the updated version.
function validate(binding) {
if (typeof binding.value !== 'function') {
// eslint-disable-next-line
console.warn('[Vue-click-outside:] provided expression', binding.expression, 'is not a function.')
return false
}
return true
}
function isPopup(popupItem, elements) {
if (!popupItem || !elements)
return false
for (var i = 0, len = elements.length; i < len; i++) {
try {
if (popupItem.contains(elements[i])) {
return true
}
if (elements[i].contains(popupItem)) {
return false
}
} catch(e) {
return false
}
}
return false
}
function isServer(vNode) {
return typeof vNode.componentInstance !== 'undefined' && vNode.componentInstance.$isServer
}
// Since IE11 doesn't support e.composedPath()
function composedPath (el) {
var path = []
while (el) {
path.push(el)
if (el.tagName === 'HTML') {
path.push(document)
path.push(window)
return path
}
el = el.parentNode
}
}
exports = module.exports = {
bind: function (el, binding, vNode) {
if (!validate(binding)) return
// Define Handler and cache it on the element
function handler(e) {
if (!vNode.context) return
// some components may have related popup item, on which we shall prevent the click outside event handler.
var elements = e.path || (e.composedPath && e.composedPath()) || composedPath(e.target)
elements && elements.length > 0 && elements.unshift(e.target)
if (el.contains(e.target) || isPopup(vNode.context.popupItem, elements)) return
el.__vueClickOutside__.callback(e)
}
// add Event Listeners
el.__vueClickOutside__ = {
handler: handler,
callback: binding.value
}
const clickHandler = 'ontouchstart' in document.documentElement ? 'touchstart' : 'click'
!isServer(vNode) && document.addEventListener(clickHandler, handler)
},
update: function (el, binding) {
if (validate(binding)) el.__vueClickOutside__.callback = binding.value
},
unbind: function (el, binding, vNode) {
// Remove Event Listeners
const clickHandler = 'ontouchstart' in document.documentElement ? 'touchstart' : 'click'
!isServer(vNode) && document.removeEventListener(clickHandler, el.__vueClickOutside__.handler)
delete el.__vueClickOutside__
}
}
Note! This does also contain the fix for IOS devices.
source code npmjs !== source code githab repo
I have a dropdown component that works well on a normal page. And I have a modal window where I use the same dropdown component. The dropdown close happens outside of the modal click, but not within the modal. Help solve this problem? Perhaps you need to include the directive globally, since the modal window component does not know about this directive? Although, why then does it work just on the page? I will be grateful for any help.
Would someone please help me understand what is happening with the mounted()
function:
I notice popupItem
is set to $el
but popupItem
is never defined.
mounted () {
// prevent click outside event with popupItem.
this.popupItem = this.$el
},
I haven't done extensive testing on this, but in using the latest version of this package straight from GitHub, rather than npm, the events failed to fire on iOS for some reason. The only device I tried this on was an iPhone 7, though I'm unsure of the Safari version (I don't own an iOS device).
I found a workaround through a similar package for React—kentor/react-click-outside, where their README mentions needing cursor: pointer
on the document.body
for iOS to see the event here:
https://github.com/kentor/react-click-outside#not-working-on-ios
After I did this, vue-click-outside
started working like a charm on a buddy's iPhone.
I'm not sure if this is something worth implementing in the package itself, or if it should be mentioned in the README since there are a number of ways to handle feature detection and adding this workaround.
Thanks!
I cannot pass a callback with params to the directive.
So, this works v-click-outside="hideMenu"
but this does not v-click-outside="handleMenuVisibility(false)"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.