Is there any proper solution for handling click-outside of elements?
there are general solutions out there, like Handling clicks outside an element without jquery :
window.onload = function() {
// For clicks inside the element
document.getElementById('myElement').onclick = function(e) {
// Make sure the event doesn't bubble from your element
if (e) { e.stopPropagation(); }
else { window.event.cancelBubble = true; }
// Place the code for this element here
alert('this was a click inside');
};
// For clicks elsewhere on the page
document.onclick = function() {
alert('this was a click outside');
};
};
But the problem is almost all projects have multiple and different popups in different components which i should handle their click-outsides.
how should i handle click-outisde without using a global window.on?(I think it is not possible to put all components outside-case handler in window.on )
After struggling with this and searching about this, i found how to solve this problem using vuejs directive without bleeding:
v-click-outside
is a good one,
https://www.npmjs.com/package/v-click-outside
//main.js import '@/directives'; ...... // directives.js import Vue from "vue"; Vue.directive('click-outside', { bind: function (element, binding, vnode) { element.clickOutsideEvent = function (event) { // check that click was outside the el and his children if (!(element === event.target || element.contains(event.target))) { // and if it did, call method provided in attribute value vnode.context[binding.expression](event); // binding.value(); run the arg } }; document.body.addEventListener('click', element.clickOutsideEvent) }, unbind: function (element) { document.body.removeEventListener('click', element.clickOutsideEvent) } });
use it every-where you want with v-click-outside directive like below:
//header.vue
<div class="profileQuickAction col-lg-4 col-md-12" v-click-outside="hidePopUps">
...
</>
you can check this on
You can also directly use VueUse vOnClickOUtside directive .
<script setup lang="ts">
import { vOnClickOutside } from '@vueuse/components'
const modal = ref(true)
function closeModal() {
modal.value = false
}
</script>
<template>
<div v-if="modal" v-on-click-outside="closeModal">
Hello World
</div>
</template>
It might be little late but i ve found a clear solution
<button class="m-search-btn" @click="checkSearch" v-bind:class="{'m-nav-active':search === true}">
methods:{
checkSearch(e){
var clicked = e.target;
this.search = !this.search;
var that = this;
window.addEventListener('click',function check(e){
if (clicked === e.target || e.target.closest('.search-input')){ //I ve used target closest to protect the input that has search bar in it
that.search = true;
}else {
that.search = false;
removeEventListener('click',check)
}
})
}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.