पता लगाने के बाहर तत्व पर क्लिक करें


121

मैं अपने तत्व के बाहर एक क्लिक का पता कैसे लगा सकता हूं? मैं Vue.js का उपयोग कर रहा हूं इसलिए यह मेरे टेम्प्लेट तत्व के बाहर होने वाला है। मुझे पता है कि वेनिला जेएस में इसे कैसे करना है, लेकिन मुझे यकीन नहीं है कि क्या ऐसा करने का अधिक उचित तरीका है, जब मैं वीयू .जे का उपयोग कर रहा हूं?

यह वेनिला जेएस के लिए समाधान है: जावास्क्रिप्ट डिटेक्ट div के बाहर घटना पर क्लिक करें

मुझे लगता है कि मैं तत्व तक पहुंचने के लिए बेहतर तरीके का उपयोग कर सकता हूं?


वाउ घटकों को अलग किया जाता है। इसलिए बाहरी परिवर्तनों का पता लगाना सवाल से बाहर है और विरोधी पैटर्न का उपयोग किया जाता है।
राज कमल

धन्यवाद। मुझे यकीन नहीं है, हालांकि इसे Vue घटक में कैसे लागू किया जाए। विरोधी पैटर्न के लिए अभी भी कुछ सर्वोत्तम अभ्यास होना चाहिए?

Vue.js घटक अलग-थलग हैं, यह सच है, लेकिन माता-पिता-बच्चे के संचार के लिए अलग-अलग तरीके हैं। इसलिए, किसी तत्व के बाहर किसी घटना का पता लगाने के लिए कहने के बजाय, आपको निर्दिष्ट करना चाहिए कि क्या आप घटक के अंदर तत्वों का पता लगाना चाहते हैं, मूल घटक से, कुछ बच्चे से, या जो भी संबंध घटकों के बीच है
येरको पाल्मा

प्रतिक्रिया के लिए धन्यवाद। क्या आपके पास कुछ उदाहरण या लिंक हैं जिनका मैं अनुसरण कर सकता हूं?

github.com/simplesmiler/vue-clickaway अपनी नौकरी को आसान बना सकता है
राज कमल

जवाबों:


97

एक बार कस्टम निर्देश सेट करके अच्छी तरह से हल किया जा सकता है:

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() }
})

उपयोग:

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

घटक में:

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

JSFiddle पर कार्य डेमो के बारे में अतिरिक्त जानकारी के साथ caveats:

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


3
मैंने vue clickaway का उपयोग किया है, लेकिन मुझे लगता है कि आपका समाधान कमोबेश यही है। धन्यवाद।

56
यह दृष्टिकोण अब Vue.js 2 में काम नहीं करता है। self.vm. $ emit कॉल एक त्रुटि संदेश देता है।
northernman

3
@Blur का उपयोग करना भी एक विकल्प है और यह समान परिणाम देने में आसान बनाता है: <input @ blur = "hide"> जहाँ Hide: function () {this.isActive = false; }
क्रज

1
उत्तर को यह बताने के लिए संपादित किया जाना चाहिए कि मैं केवल Vue.js 1 के लिए हूं
स्टीफन

167

मेरे द्वारा उपयोग किया गया समाधान है, जो लाइनस बोर्ग उत्तर पर आधारित है और vue.js 2.0 के साथ ठीक काम करता है।

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

आप इसका उपयोग करके इसे बांधते हैं v-click-outside:

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

यहाँ एक छोटा डेमो है

आप कस्टम निर्देशों और किस बारे में कुछ और जानकारी मिल सकती एल, बंधन, vnode में साधन https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments


8
काम किया है, लेकिन Vue 2.0 के निर्देशों में अब कोई उदाहरण नहीं है, इसलिए यह अपरिभाषित है। vuejs.org/v2/guide/migration.html#Custom-Directives-simplified । मुझे कोई सुराग नहीं है कि यह फिडल काम क्यों करता है या जब यह सरलीकरण किया गया है। (तत्व को घटना को बांधने के लिए "इसे" को "एल" के साथ बदलें "
बसता

1
यह संभवतः काम करता है क्योंकि खिड़की "इस" के रूप में पारित हुई। मैंने जवाब तय कर दिया है। इस बग को इंगित करने के लिए धन्यवाद।
मैडिसनट्रैश

8
क्या बाहर विशिष्ट तत्व को बाहर करने का एक तरीका है? उदाहरण के लिए, मेरे पास एक बटन है जिसे इस तत्व को खोलना है और क्योंकि यह दोनों विधियों को चलाता है कुछ भी नहीं होता है।
इल्विनास

5
क्या आप कृपया vnode.context [बाइंडिंग। एक्सप्रेशन] (घटना) की व्याख्या कर सकते हैं; ?
साईनाथ एसआर

1
इसे कैसे बदला जाए ताकि वी-क्लिक-आउट के भीतर एक अभिव्यक्ति के बजाय एक अभिव्यक्ति का उपयोग किया जा सके?
रफदको

50

tabindexअपने घटक में विशेषता जोड़ें ताकि इसे केंद्रित किया जा सके और निम्नलिखित कार्य करें:

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

4
वाह! मुझे यह सबसे छोटा और सबसे साफ समाधान लगता है। इसके अलावा केवल एक है कि मेरे मामले में काम किया।
मैट कोमर्निक

3
बस इस पर जोड़ने के लिए, -1 का टैबिन्डेक्स सेट करने पर हाइलाइट बॉक्स दिखाई देगा जब आप तत्व पर क्लिक करेंगे, लेकिन यह तब भी डिव को फोकस करने की अनुमति देगा।
कॉलिन

1
किसी कारण से -1 का टैबइंडेक्स मेरे लिए रूपरेखा नहीं छिपाता है, इसलिए मैंने सिर्फ outline: none;तत्व पर ध्यान केंद्रित किया है।
Art3mix

1
हम इसे ऑफ-कैनवास साइड नेवी पर कैसे लागू कर सकते हैं जो स्क्रीन पर स्लाइड करता है? जब तक यह क्लिक नहीं किया जाता, तब तक मैं सिद्दनव को ध्यान देने में असमर्थ हूं
चार्ल्स ओक्वाग्वु

1
यह बिल्कुल शक्तिशाली तरीका है। धन्यवाद! :)
कैनेट रॉबर्न जूल

23

इस कार्य के लिए समुदाय में दो पैकेज उपलब्ध हैं (दोनों का रखरखाव किया जाता है):


8
vue-clickawayपैकेज ने मेरी समस्या को पूरी तरह से हल कर दिया। धन्यवाद
अबदल्ला Arbab

1
बहुत सारी वस्तुओं के बारे में क्या? बाहर के क्लिक इवेंट वाली प्रत्येक वस्तु प्रत्येक क्लिक पर ईवेंट को फायर करेगी। जब आप गैलरी बनाते हैं तो संवाद और भयानक हो तो अच्छा है। गैर-घटक युग में हम दस्तावेज़ से क्लिक सुन रहे हैं और जांचें कि किस तत्व को क्लिक किया गया था। लेकिन अब यह एक दर्द है।
ब्र।

@ जुलिएन ले कूपेनेक ने इस समाधान को अब तक सबसे अच्छा पाया है! इसे साझा करने के लिए बहुत बहुत धन्यवाद!
मैनुअल अबस्कल

7

यह मेरे लिए 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
  }
}

इस उदाहरण के लिए धन्यवाद। 2.6 पर यह जाँच की। कुछ फिक्स है, unbind मेथड में आपको इसके द्वारा कुछ इशू को ठीक करना होगा (आप unbind मेथड में बॉडी प्रॉपर्टी को भूल गए): document.body.removeEventListener ('क्लिक', el .__ vueClutOutside__); यदि नहीं - यह हर घटक मनोरंजन (पृष्ठ ताज़ा) के बाद कई ईवेंट श्रोताओं के निर्माण का कारण बनेगा;
एलेक्सी शबरामोव

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

  }
}

5

मैंने सभी उत्तरों को जोड़ दिया है (vue-clickaway से एक पंक्ति सहित) और इस समाधान के साथ आया जो मेरे लिए काम करता है:

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);
    }
});

घटक में उपयोग करें:

<li v-click-outside="closeSearch">
  <!-- your component here -->
</li>

नीचे
@MadisonTrash के

3

मैंने मोबाइल सफारी का समर्थन करने के लिए मैडिसनट्रैश के उत्तर को अपडेट किया है (जिसके पास clickघटना नहीं है , touchendइसके बजाय इसका उपयोग किया जाना चाहिए)। इसमें एक चेक भी शामिल है ताकि मोबाइल उपकरणों पर खींचकर ईवेंट ट्रिगर न हो।

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');
    },
});

3

मैं इस कोड का उपयोग करता हूं:

शो-छिपाएँ बटन

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

दिखाना-छिपाना तत्व

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

लिपि

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

अपडेट: घड़ी हटाएं; प्रचार बंद करो


2

मुझे अतिरिक्त कार्यों से नफरत है ... यहाँ एक अतिरिक्त vue तरीकों के बिना एक भयानक vue समाधान है, केवल var

  1. HTML एलीमेंट बनाएं, नियंत्रण सेट करें और निर्देश दें
    <p @click="popup = !popup" v-out="popup">

    <div v-if="popup">
       My awesome popup
    </div>
  1. जैसे डेटा में एक var बनाएँ
data:{
   popup: false,
}
  1. जोड़ने के निर्देश। आईटी इस
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
    }
})

2

यदि आप विशेष रूप से तत्व के बाहर एक क्लिक की तलाश कर रहे हैं, लेकिन अभी भी माता-पिता के भीतर, आप उपयोग कर सकते हैं

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

मैं modals के लिए इस का उपयोग करें।


1

आप इस तरह क्लिक इवेंट के लिए दो ईवेंट श्रोताओं को पंजीकृत कर सकते हैं

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!");
         }
);

धन्यवाद। मुझे यह पता है, लेकिन ऐसा लगता है कि Vue.js में ऐसा करने का बेहतर तरीका होना चाहिए?

ठीक है! जवाब देने के लिए :) कुछ vue.js प्रतिभा जाने
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;
      }
    },
  },

धन्यवाद, पूरी तरह से काम करना और अगर आपको केवल एक बार अतिरिक्त पुस्तकालयों की आवश्यकता नहीं है, तो इसकी आवश्यकता है
Marian Klühspies

1

संक्षिप्त उत्तर: यह कस्टम निर्देशों के साथ किया जाना चाहिए ।

यहाँ बहुत सारे शानदार उत्तर हैं जो यह भी कहते हैं, लेकिन अधिकांश उत्तर मैंने तब देखे हैं जब आप बाहर का उपयोग बड़े पैमाने पर करना शुरू करते हैं (विशेष रूप से स्तरित या कई बहिष्कृत के साथ)। मैंने एक लेख लिखा है कस्टम निर्देश की बारीकियों और विशेष रूप से इस एक के कार्यान्वयन के बारे में बात करते हुए । यह सभी किनारे के मामलों को कवर नहीं कर सकता है लेकिन इसने मेरे द्वारा सोचे गए सभी चीजों को कवर किया है।

यह कई बाइंडिंग, कई स्तर के अन्य तत्व बहिष्करण के लिए जिम्मेदार होगा और आपके हैंडलर को केवल "व्यावसायिक तर्क" का प्रबंधन करने की अनुमति देगा।

यहां कम से कम परिभाषा वाले हिस्से के लिए कोड है, पूर्ण विवरण के लिए लेख देखें।

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

1

मैंने इसे बनाया () के भीतर एक फ़ंक्शन का उपयोग करके थोड़ा अलग तरीके से किया।

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

इस तरह, अगर कोई तत्व के बाहर क्लिक करता है, तो मेरे मामले में, मोबाइल नेवी छिपा हुआ है।

उम्मीद है की यह मदद करेगा!


1

इस प्रश्न के पहले से ही कई उत्तर हैं, और उनमें से अधिकांश समान कस्टम निर्देश विचार पर आधारित हैं। इस दृष्टिकोण के साथ समस्या यह है कि किसी को निर्देश के लिए एक विधि फ़ंक्शन को पास करना होगा, और अन्य घटनाओं की तरह सीधे कोड नहीं लिख सकता है।

मैंने एक नया पैकेज बनाया जो vue-on-clickoutअलग है। इसे बाहर की जाँच करें:

यह v-on:clickoutकिसी भी अन्य घटनाओं की तरह लिखने की अनुमति देता है । उदाहरण के लिए, आप लिख सकते हैं

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

और यह काम करता है।

अपडेट करें

vue-on-clickout अब Vue 3 का समर्थन करता है!


0

बस अगर किसी को लग रहा है कि मॉडल के बाहर क्लिक करने पर मोडल को कैसे छिपाया जाए। चूँकि मोडल में आमतौर पर इसका रैपर होता है, modal-wrapया आपके द्वारा नामित किसी भी चीज़ के साथ , आप @click="closeModal"रैपर पर रख सकते हैं । Vuejs प्रलेखन में बताए गए ईवेंट हैंडलिंग का उपयोग करते हुए , आप जांच सकते हैं कि क्लिक किए गए लक्ष्य या तो आवरण पर या मोडल पर हैं।

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>


0

@ डनीस डेनिलेंको सॉल्यूशंस मेरे लिए काम करता है, यहाँ मैंने क्या किया है: जिस तरह से मैं यहाँ VueJS CLI3 और NuxtJS का उपयोग कर रहा हूँ और बूटस्ट्रैप 4 के साथ, लेकिन यह NuxtJe के बिना VueJS पर भी काम करेगा:

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

0

आप एक निर्देश से कस्टम देशी जावास्क्रिप्ट घटना का उत्सर्जन कर सकते हैं। एक निर्देश बनाएँ जो नोड से एक घटना को भेजता है, नोड.dispatchEvent का उपयोग कर

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

जिसका उपयोग इस तरह किया जा सकता है

h3( v-out-click @click="$emit('show')" @out-click="$emit('hide')" )

0

मैं इस तरह शरीर के अंत में एक div बनाता हूं:

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

कहां है:

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

और दूर () Vue उदाहरण में एक विधि है:

away() {
 this.isPopup = false;
}

आसान, अच्छा काम करता है।


0

यदि आपके पास मूल तत्व के अंदर कई तत्वों के साथ एक घटक है तो आप इसका उपयोग कर सकते हैं। यह सिर्फ बूलियन के साथ समाधान काम करता है

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

0

इस पैकेज का उपयोग करें vue-click-बाहर

यह सरल और विश्वसनीय है, वर्तमान में कई अन्य पैकेजों द्वारा उपयोग किया जाता है। आप केवल आवश्यक घटकों में पैकेज को कॉल करके अपने जावास्क्रिप्ट बंडल आकार को कम कर सकते हैं (नीचे उदाहरण देखें)।

npm install vue-click-outside

उपयोग:

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


0

आप नए घटक बना सकते हैं जो बाहर क्लिक पर संभालते हैं

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>
`
})

और इस घटक का उपयोग करें:

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

-1

अक्सर लोग जानना चाहते हैं कि क्या उपयोगकर्ता रूट कंपोनेंट छोड़ता है (किसी भी स्तर के कंपोनेंट्स के साथ काम करता है)

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


-1

मैं ड्रॉपडाउन ड्रॉपडाउन मेनू से निपटने के लिए एक समाधान है:

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

-1

मैं इस पैकेज का उपयोग कर रहा हूं: https://www.npmjs.com/package/vue-click-outside

यह मेरे लिए ठीक काम करता है

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>

मेरी स्क्रिप्ट कोड:

import ClickOutside from 'vue-click-outside'
export default
{
    data(){
        return {
            cardContentVisible:false
        }
    },
    created()
    {
    },
    methods:
        {
            openCardContent()
            {
                this.cardContentVisible = true;
            }, hide () {
            this.cardContentVisible = false
                }
        },
    directives: {
            ClickOutside
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.