Skip to content

onClickOutside ​

Category
Export Size
1.06 kB
Last Changed
6 months ago

Listen for clicks outside of an element. Useful for modals or dropdowns.

Demo ​

Usage ​

vue
<script setup lang="ts">
import { 
onClickOutside
} from '@vueuse/core'
import {
useTemplateRef
} from 'vue'
const
target
=
useTemplateRef
('target')
onClickOutside
(
target
,
event
=>
console
.
log
(
event
))
</script> <template> <
div
ref
="
target
">
Hello world </
div
>
<
div
>Outside element</
div
>
</template>

Return Value ​

By default, onClickOutside returns a stop function to remove the event listeners.

ts
const 
stop
= onClickOutside(target, handler)
// Later, stop listening
stop
()
js
'use strict'
const stop = onClickOutside(target, handler)
// Later, stop listening
stop()

Controls ​

If you need more control over triggering the handler, you can use the controls option. This returns an object with stop, cancel, and trigger functions.

ts
const { 
stop
,
cancel
,
trigger
} = onClickOutside(
modalRef, (
event
) => {
modal.value = false }, {
controls
: true },
) // cancel prevents the next click from triggering the handler
cancel
()
// trigger manually fires the handler
trigger
(
event
)
// stop removes all event listeners
stop
()
js
'use strict'
const { stop, cancel, trigger } = onClickOutside(
  modalRef,
  (event) => {
    modal.value = false
  },
  { controls: true },
)
// cancel prevents the next click from triggering the handler
cancel()
// trigger manually fires the handler
trigger(event)
// stop removes all event listeners
stop()

Ignore Elements ​

Use the ignore option to prevent certain elements from triggering the handler. Provide elements as an array of Refs or CSS selectors.

ts
const 
ignoreElRef
=
useTemplateRef
('ignoreEl')
onClickOutside( target,
event
=>
console
.
log
(
event
),
{
ignore
: [
ignoreElRef
, '.ignore-class', '#ignore-id'] },
)
js
'use strict'
const ignoreElRef = useTemplateRef('ignoreEl')
onClickOutside(target, (event) => console.log(event), {
  ignore: [ignoreElRef, '.ignore-class', '#ignore-id'],
})

Capture Phase ​

By default, the event listener uses the capture phase (capture: true). Set capture: false to use the bubbling phase instead.

ts
onClickOutside(target, handler, { 
capture
: false })
js
'use strict'
onClickOutside(target, handler, { capture: false })

Detect Iframe Clicks ​

Clicks inside an iframe are not detected by default. Enable detectIframe to also trigger the handler when focus moves to an iframe.

ts
onClickOutside(target, handler, { 
detectIframe
: true })
js
'use strict'
onClickOutside(target, handler, { detectIframe: true })

Component Usage ​

This function also provides a renderless component version via the @vueuse/components package. Learn more about the usage.

vue
<template>
  <OnClickOutside 
:
options
="{
ignore
: [/* ... */] }" @
trigger
="count++">
<
div
>
Click Outside of Me </
div
>
</OnClickOutside> </template>

Directive Usage ​

This function also provides a directive version via the @vueuse/components package. Learn more about the usage.

vue
<script setup lang="ts">
import { 
vOnClickOutside
} from '@vueuse/components'
import {
shallowRef
} from 'vue'
const
modal
=
shallowRef
(false)
function
closeModal
() {
modal
.
value
= false
} </script> <template> <
button
@
click
="
modal
= true">
Open Modal </
button
>
<
div
v-if="
modal
"
v-on-click-outs
ide="
closeModal
">
Hello World </
div
>
</template>

You can also set the handler as an array to set the configuration items of the instruction.

vue
<script setup lang="ts">
import { 
vOnClickOutside
} from '@vueuse/components'
import {
shallowRef
,
useTemplateRef
} from 'vue'
const
modal
=
shallowRef
(false)
const
ignoreElRef
=
useTemplateRef
('ignoreEl')
const
onClickOutsideHandler
= [
(
ev
) => {
console
.
log
(
ev
)
modal
.
value
= false
}, {
ignore
: [
ignoreElRef
] },
] </script> <template> <
button
@
click
="
modal
= true">
Open Modal </
button
>
<
div
ref
="
ignoreElRef
">
click outside ignore element </
div
>
<
div
v-if="
modal
"
v-on-click-outs
ide="
onClickOutsideHandler
">
Hello World </
div
>
</template>

Type Declarations ​

Show Type Declarations
ts
export interface 
OnClickOutsideOptions
<
Controls
extends boolean = false,
> extends ConfigurableWindow { /** * List of elements that should not trigger the event, * provided as Refs or CSS Selectors. */
ignore
?:
MaybeRefOrGetter
<(
MaybeElementRef
| string)[]>
/** * Use capturing phase for internal event listener. * @default true */
capture
?: boolean
/** * Run handler function if focus moves to an iframe. * @default false */
detectIframe
?: boolean
/** * Use controls to cancel/trigger listener. * @default false */
controls
?:
Controls
} export type
OnClickOutsideHandler
<
T
extends
OnClickOutsideOptions
<boolean> =
OnClickOutsideOptions
,
> = (
event
:
| (
T
["detectIframe"] extends true ? FocusEvent : never)
| (
T
["controls"] extends true ? Event : never)
| PointerEvent, ) => void export type
OnClickOutsideReturn
<
Controls
extends boolean = false> =
Controls
extends false
?
Fn
: {
stop
:
Fn
cancel
:
Fn
trigger
: (
event
: Event) => void
} /** * Listen for clicks outside of an element. * * @see https://vueuse.org/onClickOutside * @param target * @param handler * @param options */ export declare function
onClickOutside
<
T
extends
OnClickOutsideOptions
>(
target
:
MaybeComputedElementRef
,
handler
:
OnClickOutsideHandler
<
T
>,
options
?:
T
,
):
Fn
export declare function
onClickOutside
<
T
extends
OnClickOutsideOptions
<true>>(
target
:
MaybeComputedElementRef
,
handler
:
OnClickOutsideHandler
<
T
>,
options
:
T
,
): {
stop
:
Fn
cancel
:
Fn
trigger
: (
event
: Event) => void
}

Source ​

Source • Demo • Docs

Contributors ​

Anthony Fu
sibbng
Anthony Fu
Vida Xie
Fernando Fernández
IlyaL
wheat
Robin
bab
Rainbow
IlyaL
SerKo
Melkumyants Danila
vitomir-knime
jiangsongyang
Onion-L
Matej Černý
不见月
Doctorwu
Rory King
糠帅傅
Chestnut
vaakian X
Fiad
Young
Gavin
webfansplz
Jelf
JserWang
Alex Kozack

Changelog ​

1a77b - fix: detect iframe inside shadow DOM with detectIframe option (#5336)
7133c - feat: allow the value of target to be a getter (#5098)
e5f74 - feat!: deprecate alias exports in favor of original function names (#5009)
8c521 - feat(components)!: refactor components and make them consistent (#4912)
d5812 - fix: the order of overload signatures (#4839)
1c60c - fix: workaround for iOS (#4735)
7432f - feat(types): deprecate MaybeRef and MaybeRefOrGetter in favor of Vue's native (#4636)
ab116 - feat: add controls (#4537)
c6c6e - feat: use useEventListener where it was not being used (#4479)
dd316 - feat: use passive event handlers everywhere is possible (#4477)
59f75 - feat(toValue): deprecate toValue from @vueuse/shared in favor of Vue's native
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
fe322 - feat(OnClickOutside): support component with fragments (#4313)
9e598 - fix: improve cross-browser compatibility (#4185)
aa5e3 - fix: make ignore accept reactive values (#4211)

Released under the MIT License.