Kısa cevap: Bu, Özel Direktiflerle yapılmalıdır .
Burada bunu da söyleyen birçok harika yanıt var, ancak dış tıklamayı yoğun bir şekilde kullanmaya başladığınızda (özellikle katmanlı veya birden çok dışlama ile) gördüğüm yanıtların çoğu bozulur. Özel Direktiflerin nüanslarından ve özellikle de bunun uygulanmasından bahseden ortam üzerine bir makale yazdım . Tüm uç durumları kapsamayabilir, ancak düşündüğüm her şeyi kapsamıştır.
Bu, birden çok bağlamayı, diğer öğe dışlamalarının birden çok düzeyini hesaba katacak ve işleyicinizin yalnızca "iş mantığını" yönetmesine izin verecektir.
İşte kodun en azından tanım kısmı için, tam açıklama için makaleye göz atın.
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