kliping.pro
  • Docs
  • Directory
  • Colors
  • Typeset
Hooks
  • State7
  • Advanced6
  • Lifecycle16
  • Browser21
    • useActiveElement
    • useBattery
    • useClickAnyWhere
    • useClickAway
    • useClipboard
    • useDocumentVisibility
    • useElementSize
    • useEventListener
    • useFps
    • useFullscreen
    • useHash
    • useHover
    • useInViewport
    • useIsMatchMedia
    • useIsOnline
    • useMouse
    • useNetwork
    • useOs
    • useScrollLock
    • useTextSelection
    • useTitle
  • Development1
  • Third-Party4
  • Libraries4

useActiveElement

PreviousNext

Elemen yang sedang menerima fokus.

Dipantau lewat focus dan blur pada fase capture. Itu bukan detail gaya: keduanya tidak menggelembung, jadi pendengar biasa di window tidak akan pernah mendengarnya sama sekali.

blur diabaikan kalau relatedTarget terisi — artinya fokusnya cuma pindah ke elemen lain, dan focus berikutnya sudah akan melaporkannya. Yang ditangani di sini adalah fokus yang benar-benar keluar dari halaman.

Installation ​

pnpm dlx shadcn-vue@latest add @kliping/use-active-element

Perlu @kliping terdaftar di components.json project Anda. Lihat cara menyiapkannya.

Ikut terpasang sendiri: is-browser, try-on-mounted, use-event-listener.

Salin dulu is-browser, try-on-mounted, target, use-event-listener — masing-masing memuat sumbernya di halamannya sendiri — lalu tempel berkas ini.

ts
import { getCurrentScope, onScopeDispose, readonly, shallowRef } from 'vue'
import { isBrowser } from '@/lib/is-browser'
import { tryOnMounted } from '@/lib/try-on-mounted'
import { useEventListener } from '@/composables/use-event-listener'

export interface UseActiveElementOptions {
  /** Descend into open shadow roots. Default: true. */
  deep?: boolean
  /** Re-check when DOM nodes are removed. Default: false. */
  triggerOnRemoval?: boolean
}

function findActiveElement(deep: boolean): Element | null {
  if (!isBrowser) return null

  let active: Element | null = document.activeElement
  if (!deep) return active

  while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement

  return active
}

export function useActiveElement(options: UseActiveElementOptions = {}) {
  const { deep = true, triggerOnRemoval = false } = options

  const active = shallowRef<Element | null>(null)

  const update = () => {
    active.value = findActiveElement(deep)
  }

  useEventListener('focus', update, { capture: true })
  useEventListener(
    'blur',
    (event: FocusEvent) => {
      if (event.relatedTarget !== null) return
      update()
    },
    { capture: true },
  )

  let observer: MutationObserver | undefined

  tryOnMounted(() => {
    update()

    if (!triggerOnRemoval || typeof MutationObserver === 'undefined') return

    observer = new MutationObserver(update)
    observer.observe(document, { childList: true, subtree: true })
  })

  if (getCurrentScope()) onScopeDispose(() => observer?.disconnect())

  return readonly(active)
}

API ​

ts
export interface UseActiveElementOptions {
  /** Descend into open shadow roots. Default: true. */
  deep?: boolean
  /** Re-check when DOM nodes are removed. Default: false. */
  triggerOnRemoval?: boolean
}

export function useActiveElement(options: UseActiveElementOptions = {})
PrevioususeUpdateEffectNext useBattery

On This Page

InstallationAPI
Dirilis di bawah lisensi MIT. Ditulis ulang untuk Vue dari shadcn-vue, shadcn-ui-blocks, dan shadcn-hooks. Hak cipta © 2026 Kliping