Klick außerhalb des Elements erkennen

118

Wie kann ich einen Klick außerhalb meines Elements erkennen? Ich verwende Vue.js, damit es außerhalb meines Vorlagenelements liegt. Ich weiß, wie es in Vanilla JS gemacht wird, aber ich bin mir nicht sicher, ob es einen angemesseneren Weg gibt, wenn ich Vue.js benutze?

Dies ist die Lösung für Vanilla JS: Javascript Detect Click-Ereignis außerhalb von div

Ich denke, ich kann einen besseren Weg verwenden, um auf das Element zuzugreifen.

Gemeinschaft
quelle
Vue-Komponenten sind isoliert. Das Erkennen von äußeren Veränderungen kommt daher nicht in Frage, und es wird ein Anti-Pattern verwendet.
Raj Kamal
Vielen Dank. Ich bin mir jedoch nicht sicher, wie ich es in einer Vue-Komponente implementieren soll. Es muss noch einige Best Practices für das Anti-Pattern geben?
Die Vue.js-Komponente ist zwar isoliert, es gibt jedoch verschiedene Methoden für die Eltern-Kind-Kommunikation. Anstatt zu fragen, ob ein Ereignis außerhalb eines Elements erkannt werden soll, sollten Sie angeben, ob Sie Elemente innerhalb einer Komponente, der übergeordneten Komponente, eines untergeordneten Elements oder einer Beziehung zwischen Komponenten erkennen möchten
Yerko Palma
Danke für die Rückmeldung. Haben Sie einige Beispiele oder Links, denen ich folgen kann?
github.com/simplesmiler/vue-clickaway kann Ihre Arbeit vereinfachen
Raj Kamal

Antworten:

95

Kann durch einmaliges Einrichten einer benutzerdefinierten Direktive gelöst werden:

Vue.directive('click-outside', {
  bind () {
      this.event = event => this.vm.$emit(this.expression, event)
      this.el.addEventListener('click', this.stopProp)
      document.body.addEventListener('click', this.event)
  },   
  unbind() {
    this.el.removeEventListener('click', this.stopProp)
    document.body.removeEventListener('click', this.event)
  },

  stopProp(event) { event.stopPropagation() }
})

Verwendung:

<div v-click-outside="nameOfCustomEventToCall">
  Some content
</div>

In der Komponente:

events: {
  nameOfCustomEventToCall: function (event) {
    // do something - probably hide the dropdown menu / modal etc.
  }
}

Arbeitsdemo zu JSFiddle mit zusätzlichen Informationen zu Vorbehalten:

https://jsfiddle.net/Linusborg/yzm8t8jq/

Linus Borg
quelle
3
Ich habe den vue clickaway verwendet, aber ich denke, Ihre Lösung ist mehr oder weniger dieselbe. Vielen Dank.
56
Dieser Ansatz funktioniert in Vue.js 2 nicht mehr. Der Aufruf self.vm. $ emit gibt eine Fehlermeldung aus.
Nordmann
3
Die Verwendung von @blur ist ebenfalls eine Option und erleichtert das Erreichen des gleichen Ergebnisses: <input @ blur = "hide"> wobei hide: function () {this.isActive = false; }
Craws
1
Die Antwort sollte so bearbeitet werden, dass sie nur für Vue.js 1
Stéphane Gerber
167

Es gibt die Lösung, die ich verwendet habe, die auf der Antwort von Linus Borg basiert und mit vue.js 2.0 gut funktioniert.

Vue.directive('click-outside', {
  bind: function (el, binding, vnode) {
    el.clickOutsideEvent = function (event) {
      // here I check that click was outside the el and his children
      if (!(el == event.target || el.contains(event.target))) {
        // and if it did, call method provided in attribute value
        vnode.context[binding.expression](event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unbind: function (el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  },
});

Sie binden daran mit v-click-outside:

<div v-click-outside="doStuff">

Hier ist eine kleine Demo

Sie können einige weitere Informationen über benutzerdefinierte Richtlinien finden und was el, Bindung, V - Knoten Mittel in https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments

MadisonTrash
quelle
8
Funktioniert, aber in Vue 2.0 haben Direktiven keine Instanz mehr, daher ist dies undefiniert. vuejs.org/v2/guide/migration.html#Custom-Directives-simplified . Ich habe keine Ahnung, warum diese Geige funktioniert oder wann diese Vereinfachung vorgenommen wurde. (Um zu lösen, ersetzen Sie "dies" durch "el", um das Ereignis an das Element zu binden)
Busata
1
Es funktioniert wahrscheinlich, weil das Fenster als "dies" übergeben wurde. Ich habe die Antwort korrigiert. Vielen Dank, dass Sie auf diesen Fehler hingewiesen haben.
MadisonTrash
8
Gibt es eine Möglichkeit, ein bestimmtes Element außerhalb auszuschließen? Zum Beispiel habe ich eine Schaltfläche außerhalb, die dieses Element öffnen muss, und da beide Methoden ausgelöst werden, passiert nichts.
Žilvinas
5
Können Sie bitte vnode.context [binding.expression] (Ereignis) erklären? ?
Sainath SR
1
Wie kann man dies ändern, damit ein Ausdruck anstelle einer Methode innerhalb des V-Click-Outside verwendet werden kann?
Raphadko
50

Fügen Sie tabindexIhrer Komponente ein Attribut hinzu, damit sie fokussiert werden kann, und führen Sie folgende Schritte aus:

<template>
    <div
        @focus="handleFocus"
        @focusout="handleFocusOut"
        tabindex="0"
    >
      SOME CONTENT HERE
    </div>
</template>

<script>
export default {    
    methods: {
        handleFocus() {
            // do something here
        },
        handleFocusOut() {
            // do something here
        }
    }
}
</script>
G'ofur N.
quelle
4
Whoa! Ich finde das die kürzeste und sauberste Lösung. Auch der einzige, der in meinem Fall funktioniert hat.
Matt Komarnicki
3
Wenn Sie nur einen Tabindex von -1 festlegen, wird das Markierungsfeld nicht mehr angezeigt, wenn Sie auf das Element klicken. Das Div kann jedoch weiterhin fokussiert werden.
Colin
1
Aus irgendeinem Grund verbirgt der Tabindex -1 den Umriss für mich nicht, deshalb habe ich nur den outline: none;Fokus für das Element hinzugefügt .
Art3mix
1
Wie können wir dies auf ein Off-Canvas-Seitennavigation anwenden, das auf den Bildschirm gleitet? Ich kann den Sidenav-Fokus nur geben, wenn darauf geklickt wird.
Charles Okwuagwu
1
Dies ist absolut der mächtigste Weg. Danke dir! :)
Canet Robern
23

Für diese Aufgabe stehen in der Community zwei Pakete zur Verfügung (beide werden verwaltet):

Julien Le Coupanec
quelle
8
vue-clickawayPaket löste mein Problem perfekt. Vielen Dank
Abdalla Arbab
1
Was ist mit vielen Gegenständen? Jedes Element mit einem externen Klickereignis löst bei jedem Klick ein Ereignis aus. Es ist schön, wenn Sie Dialoge machen, und schrecklich, wenn Sie eine Galerie erstellen. In der Nicht-Komponenten-Ära hören wir das Klicken aus dem Dokument und überprüfen, auf welches Element geklickt wurde. Aber jetzt ist es ein Schmerz.
br.
@ Julien Le Coupanec Ich habe diese Lösung bei weitem als die beste gefunden! Vielen Dank für das Teilen!
Manuel Abascal
7

Dies funktionierte bei mir mit Vue.js 2.5.2:

/**
 * Call a function when a click is detected outside of the
 * current DOM node ( AND its children )
 *
 * Example :
 *
 * <template>
 *   <div v-click-outside="onClickOutside">Hello</div>
 * </template>
 *
 * <script>
 * import clickOutside from '../../../../directives/clickOutside'
 * export default {
 *   directives: {
 *     clickOutside
 *   },
 *   data () {
 *     return {
         showDatePicker: false
 *     }
 *   },
 *   methods: {
 *     onClickOutside (event) {
 *       this.showDatePicker = false
 *     }
 *   }
 * }
 * </script>
 */
export default {
  bind: function (el, binding, vNode) {
    el.__vueClickOutside__ = event => {
      if (!el.contains(event.target)) {
        // call method provided in v-click-outside value
        vNode.context[binding.expression](event)
        event.stopPropagation()
      }
    }
    document.body.addEventListener('click', el.__vueClickOutside__)
  },
  unbind: function (el, binding, vNode) {
    // Remove Event Listeners
    document.removeEventListener('click', el.__vueClickOutside__)
    el.__vueClickOutside__ = null
  }
}
yann_yinn
quelle
Vielen Dank für dieses Beispiel. Überprüft dies auf Vue 2.6. Es gibt einige Korrekturen, bei der Methode zum Aufheben der Bindung müssen Sie ein Problem beheben (Sie haben die Eigenschaft body in der Methode zum Aufheben der Bindung vergessen): document.body.removeEventListener ('click', el .__ vueClickOutside__); Wenn nicht, werden nach jeder Neuerstellung der Komponenten (Seitenaktualisierung) mehrere Ereignis-Listener erstellt.
Alexey Shabramov
7
export default {
  bind: function (el, binding, vNode) {
    // Provided expression must evaluate to a function.
    if (typeof binding.value !== 'function') {
      const compName = vNode.context.name
      let warn = `[Vue-click-outside:] provided expression '${binding.expression}' is not a function, but has to be`
      if (compName) { warn += `Found in component '${compName}'` }

      console.warn(warn)
    }
    // Define Handler and cache it on the element
    const bubble = binding.modifiers.bubble
    const handler = (e) => {
      if (bubble || (!el.contains(e.target) && el !== e.target)) {
        binding.value(e)
      }
    }
    el.__vueClickOutside__ = handler

    // add Event Listeners
    document.addEventListener('click', handler)
  },

  unbind: function (el, binding) {
    // Remove Event Listeners
    document.removeEventListener('click', el.__vueClickOutside__)
    el.__vueClickOutside__ = null

  }
}
xiaoyu2er
quelle
5

Ich habe alle Antworten kombiniert (einschließlich einer Zeile von vue-clickaway) und eine Lösung gefunden, die für mich funktioniert:

Vue.directive('click-outside', {
    bind(el, binding, vnode) {
        var vm = vnode.context;
        var callback = binding.value;

        el.clickOutsideEvent = function (event) {
            if (!(el == event.target || el.contains(event.target))) {
                return callback.call(vm, event);
            }
        };
        document.body.addEventListener('click', el.clickOutsideEvent);
    },
    unbind(el) {
        document.body.removeEventListener('click', el.clickOutsideEvent);
    }
});

Verwendung in der Komponente:

<li v-click-outside="closeSearch">
  <!-- your component here -->
</li>
BogdanG
quelle
Ziemlich genau das gleiche wie @ MadisonTrash Antwort unten
Retrovertigo
3

Ich habe die Antwort von MadisonTrash aktualisiert, um Mobile Safari zu unterstützen (die kein clickEreignis hat touchendund stattdessen verwendet werden muss). Dies beinhaltet auch eine Überprüfung, damit das Ereignis nicht durch Ziehen auf Mobilgeräten ausgelöst wird.

Vue.directive('click-outside', {
    bind: function (el, binding, vnode) {
        el.eventSetDrag = function () {
            el.setAttribute('data-dragging', 'yes');
        }
        el.eventClearDrag = function () {
            el.removeAttribute('data-dragging');
        }
        el.eventOnClick = function (event) {
            var dragging = el.getAttribute('data-dragging');
            // Check that the click was outside the el and its children, and wasn't a drag
            if (!(el == event.target || el.contains(event.target)) && !dragging) {
                // call method provided in attribute value
                vnode.context[binding.expression](event);
            }
        };
        document.addEventListener('touchstart', el.eventClearDrag);
        document.addEventListener('touchmove', el.eventSetDrag);
        document.addEventListener('click', el.eventOnClick);
        document.addEventListener('touchend', el.eventOnClick);
    }, unbind: function (el) {
        document.removeEventListener('touchstart', el.eventClearDrag);
        document.removeEventListener('touchmove', el.eventSetDrag);
        document.removeEventListener('click', el.eventOnClick);
        document.removeEventListener('touchend', el.eventOnClick);
        el.removeAttribute('data-dragging');
    },
});
benrwb
quelle
3

Ich benutze diesen Code:

Schaltfläche zum Ausblenden

 <a @click.stop="visualSwitch()"> show hide </a>

show-hide-Element

<div class="dialog-popup" v-if="visualState" @click.stop=""></div>

Skript

data () { return {
    visualState: false,
}},
methods: {
    visualSwitch() {
        this.visualState = !this.visualState;
        if (this.visualState)
            document.addEventListener('click', this.visualState);
        else
            document.removeEventListener('click', this.visualState);
    },
},

Update: Uhr entfernen; Stop Propagation hinzufügen

Pax Exterminatus
quelle
2

Ich hasse zusätzliche Funktionen, also ... hier ist eine großartige Vue-Lösung ohne zusätzliche Vue-Methoden, nur var

  1. HTML-Element erstellen, Steuerelemente und Direktive festlegen
    <p @click="popup = !popup" v-out="popup">

    <div v-if="popup">
       My awesome popup
    </div>
  1. Erstellen Sie eine Variable in Daten wie
data:{
   popup: false,
}
  1. Vue-Direktive hinzufügen. es ist
Vue.directive('out', {

    bind: function (el, binding, vNode) {
        const handler = (e) => {
            if (!el.contains(e.target) && el !== e.target) {
                //and here is you toggle var. thats it
                vNode.context[binding.expression] = false
            }
        }
        el.out = handler
        document.addEventListener('click', handler)
    },

    unbind: function (el, binding) {
        document.removeEventListener('click', el.out)
        el.out = null
    }
})
Martin Prestone
quelle
2

Wenn Sie speziell nach einem Klick außerhalb des Elements suchen, aber immer noch innerhalb des übergeordneten Elements, können Sie verwenden

<div class="parent" @click.self="onParentClick">
  <div class="child"></div>
</div>

Ich benutze dies für Modalitäten.

Andres Holguin
quelle
1

Sie können zwei Ereignis-Listener für ein solches Klickereignis registrieren

document.getElementById("some-area")
        .addEventListener("click", function(e){
        alert("You clicked on the area!");
        e.stopPropagation();// this will stop propagation of this event to upper level
     }
);

document.body.addEventListener("click", 
   function(e) {
           alert("You clicked outside the area!");
         }
);
saravanakumar
quelle
Vielen Dank. Ich weiß das, aber es scheint, dass es in Vue.js einen besseren Weg geben muss, dies zu tun?
OK! Lassen Sie einige vue.js Genie zu antworten :)
Saravanakumar
1
  <button 
    class="dropdown"
    @click.prevent="toggle"
    ref="toggle"
    :class="{'is-active': isActiveEl}"
  >
    Click me
  </button>

  data() {
   return {
     isActiveEl: false
   }
  }, 
  created() {
    window.addEventListener('click', this.close);
  },
  beforeDestroy() {
    window.removeEventListener('click', this.close);
  },
  methods: {
    toggle: function() {
      this.isActiveEl = !this.isActiveEl;
    },
    close(e) {
      if (!this.$refs.toggle.contains(e.target)) {
        this.isActiveEl = false;
      }
    },
  },
Dmytro Lishtvan
quelle
Danke, funktioniert perfekt und wenn Sie es nur einmal brauchen, brauchen Sie keine zusätzlichen Bibliotheken
Marian Klühspies
1

Es gibt bereits viele Antworten auf diese Frage, und die meisten basieren auf der ähnlichen Idee einer benutzerdefinierten Richtlinie. Das Problem bei diesem Ansatz ist, dass man eine Methodenfunktion an die Direktive übergeben muss und nicht wie bei anderen Ereignissen direkt Code schreiben kann.

Ich habe ein neues Paket erstellt vue-on-clickout, das anders ist. Schau es dir an unter:

Es erlaubt einem, v-on:clickoutwie jedes andere Ereignis zu schreiben . Zum Beispiel können Sie schreiben

<div v-on:clickout="myField=value" v-on:click="myField=otherValue">...</div>

und es funktioniert.

Mu-Tsun Tsai
quelle
1

Die kurze Antwort: Dies sollte mit benutzerdefinierten Richtlinien erfolgen .

Es gibt hier viele großartige Antworten, die dies auch sagen, aber die meisten Antworten, die ich gesehen habe, brechen zusammen, wenn Sie anfangen, Außenklicks ausgiebig zu verwenden (insbesondere geschichtet oder mit mehreren Ausschlüssen). Ich habe einen Artikel geschrieben auf Medium geschrieben, in dem es um die Nuancen von Zollrichtlinien und die spezifische Umsetzung dieser Richtlinie geht. Es deckt möglicherweise nicht alle Randfälle ab, aber es hat alles abgedeckt, was ich mir ausgedacht habe.

Dies berücksichtigt mehrere Bindungen, mehrere Ebenen anderer Elementausschlüsse und ermöglicht Ihrem Handler, nur die "Geschäftslogik" zu verwalten.

Hier ist der Code für mindestens den Definitionsteil. Weitere Informationen finden Sie im Artikel.

var handleOutsideClick={}
const OutsideClick = {
  // this directive is run on the bind and unbind hooks
  bind (el, binding, vnode) {
    // Define the function to be called on click, filter the excludes and call the handler
    handleOutsideClick[el.id] = e => {
      e.stopPropagation()
      // extract the handler and exclude from the binding value
      const { handler, exclude } = binding.value
      // set variable to keep track of if the clicked element is in the exclude list
      let clickedOnExcludedEl = false
      // if the target element has no classes, it won't be in the exclude list skip the check
      if (e.target._prevClass !== undefined) {
        // for each exclude name check if it matches any of the target element's classes
        for (const className of exclude) {
          clickedOnExcludedEl = e.target._prevClass.includes(className)
          if (clickedOnExcludedEl) {
            break // once we have found one match, stop looking
          }
        }
      }
      // don't call the handler if our directive element contains the target element
      // or if the element was in the exclude list
      if (!(el.contains(e.target) || clickedOnExcludedEl)) {
        handler()
      }
    }
    // Register our outsideClick handler on the click/touchstart listeners
    document.addEventListener('click', handleOutsideClick[el.id])
    document.addEventListener('touchstart', handleOutsideClick[el.id])
    document.onkeydown = e => {
      //this is an option but may not work right with multiple handlers
      if (e.keyCode === 27) {
        // TODO: there are minor issues when escape is clicked right after open keeping the old target
        handleOutsideClick[el.id](e)
      }
    }
  },
  unbind () {
    // If the element that has v-outside-click is removed, unbind it from listeners
    document.removeEventListener('click', handleOutsideClick[el.id])
    document.removeEventListener('touchstart', handleOutsideClick[el.id])
    document.onkeydown = null //Note that this may not work with multiple listeners
  }
}
export default OutsideClick
Marcus Smith
quelle
1

Ich habe es etwas anders gemacht, indem ich eine Funktion in created () verwendet habe.

  created() {
      window.addEventListener('click', (e) => {
        if (!this.$el.contains(e.target)){
          this.showMobileNav = false
        }
      })
  },

Auf diese Weise wird in meinem Fall das mobile Navigationssystem ausgeblendet, wenn jemand außerhalb des Elements klickt.

Hoffe das hilft!

Fast Pitt
quelle
0

Nur wenn jemand sucht, wie man Modal versteckt, wenn man außerhalb des Modals klickt. Da Modal normalerweise einen Wrapper mit der Klasse modal-wrapoder einem von Ihnen benannten @click="closeModal"Wrapper hat, können Sie den Wrapper anlegen . Mit Ereignisbehandlung in vuejs Dokumentation erwähnt, können Sie überprüfen , ob das klickten Ziel entweder auf der Verpackung oder auf der Modal ist.

methods: {
  closeModal(e) {
    this.event = function(event) {
      if (event.target.className == 'modal-wrap') {
        // close modal here
        this.$store.commit("catalog/hideModal");
        document.body.removeEventListener("click", this.event);
      }
    }.bind(this);
    document.body.addEventListener("click", this.event);
  },
}
<div class="modal-wrap" @click="closeModal">
  <div class="modal">
    ...
  </div>
<div>

Jedi
quelle
0

@ Denis Danilenko-Lösungen funktionieren für mich wie folgt: Übrigens, ich verwende VueJS CLI3 und NuxtJS hier und mit Bootstrap4, aber es funktioniert auch auf VueJS ohne NuxtJS:

<div
    class="dropdown ml-auto"
    :class="showDropdown ? null : 'show'">
    <a 
        href="#" 
        class="nav-link" 
        role="button" 
        id="dropdownMenuLink" 
        data-toggle="dropdown" 
        aria-haspopup="true" 
        aria-expanded="false"
        @click="showDropdown = !showDropdown"
        @blur="unfocused">
        <i class="fas fa-bars"></i>
    </a>
    <div 
        class="dropdown-menu dropdown-menu-right" 
        aria-labelledby="dropdownMenuLink"
        :class="showDropdown ? null : 'show'">
        <nuxt-link class="dropdown-item" to="/contact">Contact</nuxt-link>
        <nuxt-link class="dropdown-item" to="/faq">FAQ</nuxt-link>
    </div>
</div>
export default {
    data() {
        return {
            showDropdown: true
        }
    },
    methods: {
    unfocused() {
        this.showDropdown = !this.showDropdown;
    }
  }
}
alfieindesigns
quelle
0

Sie können ein benutzerdefiniertes natives Javascript-Ereignis aus einer Direktive ausgeben. Erstellen Sie mit node.dispatchEvent eine Anweisung, die ein Ereignis vom Knoten auslöst

let handleOutsideClick;
Vue.directive('out-click', {
    bind (el, binding, vnode) {

        handleOutsideClick = (e) => {
            e.stopPropagation()
            const handler = binding.value

            if (el.contains(e.target)) {
                el.dispatchEvent(new Event('out-click')) <-- HERE
            }
        }

        document.addEventListener('click', handleOutsideClick)
        document.addEventListener('touchstart', handleOutsideClick)
    },
    unbind () {
        document.removeEventListener('click', handleOutsideClick)
        document.removeEventListener('touchstart', handleOutsideClick)
    }
})

Welches kann so verwendet werden

h3( v-out-click @click="$emit('show')" @out-click="$emit('hide')" )
Pedro Torchio
quelle
0

Ich erstelle so ein Div am Ende des Körpers:

<div v-if="isPopup" class="outside" v-on:click="away()"></div>

Wo .outside ist:

.outside {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0px;
  left: 0px;
}

Und away () ist eine Methode in der Vue-Instanz:

away() {
 this.isPopup = false;
}

Einfach, funktioniert gut.

Arnaud LiDz
quelle
0

Wenn Sie eine Komponente mit mehreren Elementen innerhalb des Stammelements haben, können Sie diese Lösung verwenden. Es funktioniert nur ™ mit einem Booleschen Wert.

<template>
  <div @click="clickInside"></div>
<template>
<script>
export default {
  name: "MyComponent",
  methods: {
    clickInside() {
      this.inside = true;
      setTimeout(() => (this.inside = false), 0);
    },
    clickOutside() {
      if (this.inside) return;
      // handle outside state from here
    }
  },
  created() {
    this.__handlerRef__ = this.clickOutside.bind(this);
    document.body.addEventListener("click", this.__handlerRef__);
  },
  destroyed() {
    document.body.removeEventListener("click", this.__handlerRef__);
  },
};
</script>
A1rPun
quelle
0

Verwenden Sie dieses Paket Vue-Click-Outside

Es ist einfach und zuverlässig und wird derzeit von vielen anderen Paketen verwendet. Sie können die Größe Ihres Javascript-Bundles auch reduzieren, indem Sie das Paket nur in den erforderlichen Komponenten aufrufen (siehe Beispiel unten).

npm install vue-click-outside

Verwendung :

<template>
  <div>
    <div v-click-outside="hide" @click="toggle">Toggle</div>
    <div v-show="opened">Popup item</div>
  </div>
</template>

<script>
import ClickOutside from 'vue-click-outside'

export default {
  data () {
    return {
      opened: false
    }
  },

  methods: {
    toggle () {
      this.opened = true
    },

    hide () {
      this.opened = false
    }
  },

  mounted () {
    // prevent click outside event with popupItem.
    this.popupItem = this.$el
  },

  // do not forget this section
  directives: {
    ClickOutside
  }
}
</script>
Smit Patel
quelle
0

Erfinden Sie das Rad nicht neu, verwenden Sie dieses Paket mit V-Click-Outside

snehanshu.js
quelle
Schauen Sie sich meine Antwort an, von der ich vermute, dass sie Ihnen besser gefällt.
Mu-Tsun Tsai
0

Sie können eine neue Komponente erstellen, die das Klicken von außen verarbeitet

Vue.component('click-outside', {
  created: function () {
    document.body.addEventListener('click', (e) => {
       if (!this.$el.contains(e.target)) {
            this.$emit('clickOutside');
           
        })
  },
  template: `
    <template>
        <div>
            <slot/>
        </div>
    </template>
`
})

Und verwenden Sie diese Komponente:

<template>
    <click-outside @clickOutside="console.log('Click outside Worked!')">
      <div> Your code...</div>
    </click-outside>
</template>
Diktator47
quelle
-1

Häufig möchten Benutzer wissen, ob Benutzer die Root-Komponente verlassen (funktioniert mit allen Level-Komponenten).

Vue({
  data: {},
  methods: {
    unfocused : function() {
      alert('good bye');
    }
  }
})
<template>
  <div tabindex="1" @blur="unfocused">Content inside</div>
</template>

Denis Danilenko
quelle
-1

Ich habe eine Lösung für die Handhabung des Umschalt-Dropdown-Menüs:

export default {
data() {
  return {
    dropdownOpen: false,
  }
},
methods: {
      showDropdown() {
        console.log('clicked...')
        this.dropdownOpen = !this.dropdownOpen
        // this will control show or hide the menu
        $(document).one('click.status', (e)=> {
          this.dropdownOpen = false
        })
      },
}
Nicolas S.Xu.
quelle
-1

Ich verwende dieses Paket: https://www.npmjs.com/package/vue-click-outside

Es funktioniert gut für mich

HTML:

<div class="__card-content" v-click-outside="hide" v-if="cardContentVisible">
    <div class="card-header">
        <input class="subject-input" placeholder="Subject" name=""/>
    </div>
    <div class="card-body">
        <textarea class="conversation-textarea" placeholder="Start a conversation"></textarea>
    </div>
</div>

Meine Skriptcodes:

import ClickOutside from 'vue-click-outside'
export default
{
    data(){
        return {
            cardContentVisible:false
        }
    },
    created()
    {
    },
    methods:
        {
            openCardContent()
            {
                this.cardContentVisible = true;
            }, hide () {
            this.cardContentVisible = false
                }
        },
    directives: {
            ClickOutside
    }
}
Murad Shukurlu
quelle