onVisible

When you already have a ref to a node, onVisible(node, fn, opts?) calls fn with each real IntersectionObserverEntry — the side-effect half of the pota/use/intersection emitter pair. For a reactive accessor use useVisible; to attach an observer declaratively use visible.

fn is never invoked with the pre-observer placeholder: the emitter emits undefined before the first real entry arrives, and onVisible filters that out. With opts.once, fn runs only for the first entry where isIntersecting is true — exit entries before it, and everything after it, are ignored.

Arguments

Argument Type Description
node Element Element to observe.
fn (entry: IntersectionObserverEntry) => void Called on each real intersection change.
opts IntersectionObserverInit & { once?: boolean } Optional. Standard root / rootMargin / threshold, plus once to fire only on first arrival.

Returns: void.

Examples

Subscribe to intersection

Logs whenever the node enters or leaves the viewport. The subscription happens inside a use:ref function, where the node actually exists; entry is always a real IntersectionObserverEntry.

import { render, signal } from 'pota'
import { onVisible } from 'pota/use/intersection'

function Panel() {
	const log = signal('')

	const watch = node =>
		onVisible(node, entry =>
			log.write(`visible: ${entry.isIntersecting}`),
		)

	return (
		<div>
			<div
				use:ref={watch}
				style={{ height: '120vh' }}
			>
				scroll me
			</div>
			<p>{log.read}</p>
		</div>
	)
}

render(Panel)

Fire once on first arrival

With once, fn runs a single time — the first entry where isIntersecting is true. Exit entries before that, and everything after it, are ignored.

import { render, signal } from 'pota'
import { onVisible } from 'pota/use/intersection'

function RevealOnce() {
	const seen = signal(false)

	return (
		<div
			use:ref={node =>
				onVisible(node, () => seen.write(true), { once: true })
			}
			style={{ height: '40vh' }}
		>
			{() => (seen.read() ? 'arrived' : 'scroll me into view')}
		</div>
	)
}

render(RevealOnce)