Giter Club home page Giter Club logo

click-outside's Introduction

vue-bulma

A modern UI framework based on Vue and Bulma.

Install

Install with npm:

$ npm i vue-bulma --save

Install with yarn:

$ yarn add vue-bulma

Example

import Vue from 'vue'
import * as components from 'vue-bulma'

// In the global registration
for (const [key, value] of Object.entries(components)) {
  const name = value.name || `vb-${key.toLowerCase()}`
  Vue.component(name, value)
}

Development

We use Lerna to manage multiple packages.

$ npm i lerna --global 
$ yarn bootstrap

Open Examples

$ yarn dev

Format packages

$ yarn run format

Create a package

# vue-bulma-container
$ lerna create vue-bulma-container
$ lerna add vue packages/vue-bulma-container/
$ lerna add bulma packages/vue-bulma-container/
$ cd packages/vue-bulma-container/
$ mkdir src
$ touch src/main.js
$ touch src/style.scss

Add to vue-bulma

$ lerna add vue-bulma-container packages/vue-bulma/

Team

Lead Maintainers

Collaborators

License

Licensed under MIT.

click-outside's People

Contributors

chooo7 avatar edbailey avatar fundon avatar luventa avatar monocles avatar pqt avatar randomknowledge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

click-outside's Issues

SSR not supported

Missing support for Server Side Rendering: invoking document.addEventListener('click', handler) doesn't work at server-side.

Does not work with IE11, but I have a fix

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.

button inside component with directive triggers event

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.

JS error on unbind

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)

Cannot call function with params

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)"

drag mouse outside element fires the event

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.

Export as IIFE for UNPKG

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.

ClickOutside not working on iOS devices

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!

`update` method prevents unbinding

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.

How to prevent click outside?

Hi, with this plugin we can capture outside events, but cannot prevent it like event.preventDefault

Is it possible in vue.js way ?

Doesn't work on vue 3

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/

Event is fired on the same click that triggers the render of the component that uses the directive.

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.

Make the event trigger at the event capture stage

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.

mounted() function

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
  },

Doesn't work in modal window

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.