如何检测元素外的点击?我正在使用 Vue.js,所以它会在我的模板元素之外。我知道如何在 Vanilla JS 中做到这一点,但是当我使用 Vue.js 时,我不确定是否有更合适的方法来做到这一点?
这是 Vanilla JS 的解决方案:Javascript Detect Click event outside of div
我想我可以使用更好的方式来访问元素?
如何检测元素外的点击?我正在使用 Vue.js,所以它会在我的模板元素之外。我知道如何在 Vanilla JS 中做到这一点,但是当我使用 Vue.js 时,我不确定是否有更合适的方法来做到这一点?
这是 Vanilla JS 的解决方案:Javascript Detect Click event outside of div
我想我可以使用更好的方式来访问元素?
有一个我使用的解决方案,它基于 Linus Borg 的答案,并且在 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">
您可以在https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments 中找到有关自定义指令的更多信息以及el、binding、vnode 的含义
请注意,此解决方案仅适用于 Vue 1。
可以通过设置一次自定义指令很好地解决:
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 上的工作演示以及有关警告的附加信息:
将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>
此答案基于 MadisonTrash上面的精彩答案,但已更新为使用新的 Vue 3 语法。
Vue 3 现在使用beforeMount
代替bind
,unmounted
代替unbind
( src )。
const clickOutside = {
beforeMount: (el, binding) => {
el.clickOutsideEvent = 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
binding.value();
}
};
document.addEventListener("click", el.clickOutsideEvent);
},
unmounted: el => {
document.removeEventListener("click", el.clickOutsideEvent);
},
};
createApp(App)
.directive("click-outside", clickOutside)
.mount("#app");