A lightweight utility to detect clicks outside a specified element, compatible with any JavaScript framework such as React, Vue, Svelte, or vanilla JavaScript. Supports TypeScript, iOS compatibility, and customizable options like ignoring elements, iframe detection, and event capture.
# npm
npm install clickout-lite
# yarn
yarn add clickout-lite
# pnpm
pnpm add clickout-lite
Below are examples demonstrating how to use clickout-lite in different frameworks.
Detect clicks outside a specific element in a Vue 3 application using the Composition API.
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { onClickOutside } from 'clickout-lite'
const containerRef = ref(null)
onMounted(() => {
   onClickOutside(containerRef, () => {
      console.log('Clicked outside the container!')
   })
})
</script>
<template>
   <div ref="containerRef" style="width: 200px; height: 200px; background: lightblue;">
      Click outside this box
   </div>
</template>
Detect clicks outside a specific element in a React application using hooks.
import React, { useRef, useEffect } from 'react'
import { onClickOutside } from 'clickout-lite'
function App() {
   const containerRef = useRef(null)
   useEffect(() => {
      const stop = onClickOutside(containerRef.current, () => {
         console.log('Clicked outside the container!')
      })
      return () => stop() // Cleanup on unmount
   }, [])
   return (
      <div
         ref={containerRef}
         style={{
            width: '200px',
            height: '200px',
            background: 'lightblue',
         }}>
         Click outside this box
      </div>
   )
}
export default App
Use clickout-lite in a plain JavaScript project.
import { onClickOutside } from 'clickout-lite'
const container = document.querySelector('#my-container')
const stop = onClickOutside(container, () => {
   console.log('Clicked outside the container!')
})
// Cleanup when done
// stop()
Detect clicks outside an element in a Svelte application.
<script>
  import { onMount, onDestroy } from 'svelte'
  import { onClickOutside } from 'clickout-lite'
  let container
  onMount(() => {
    const stop = onClickOutside(container, () => {
      console.log('Clicked outside the container!')
    })
    return () => stop() // Cleanup on destroy
  })
</script>
<div bind:this={container} style="width: 200px; height: 200px; background: lightblue;">
  Click outside this box
</div>
Ignore specific elements or enable iframe detection.
import { onClickOutside } from 'clickout-lite'
const container = document.querySelector('#my-container')
const ignoreElement = document.querySelector('#ignore-this')
onClickOutside(
   container,
   () => {
      console.log('Clicked outside the container!')
   },
   {
      ignore: [ignoreElement, '.ignore-class'], // Ignore specific elements or selectors
      detectIframe: true, // Trigger on iframe focus
      capture: false, // Use non-capturing event listener
   }
)
onClickOutside(target, handler, options?)| Parameter | Type | Description | 
|---|---|---|
| target | MaybeRefOrGetter<MaybeElementRef> | The element or ref to monitor for outside clicks. Supports direct elements, refs, or getters. | 
| handler | OnClickOutsideHandler | Callback function triggered when a click occurs outside the target. | 
| options | OnClickOutsideOptions | Optional configuration object. | 
| Option | Type | Default | Description | 
|---|---|---|---|
| ignore | MaybeRefOrGetter<(MaybeElementRef | string)[]> | [] | Elements or selectors to ignore for click detection. | 
| capture | boolean | true | Whether to use capturing event listeners. | 
| detectIframe | boolean | false | Trigger handler on iframe focus events. | 
| controls | boolean | false | Return control methods ( stop,cancel,trigger) instead of juststop. | 
| window | Window | globalThis.window | Custom window object for testing or special environments. | 
options.controls is false: Returns a stop function to remove event listeners.options.controls is true: Returns an object with stop, cancel, and trigger methods.