利用規約を全部読んだら押せるチェックボックスを作りたい
これを使えばできそう
利用規約をoverflow-scrollな固定hのBoxに記載して、最下部までスクロールしたら「全部読みました」のcheckboxをenabledにしたい
端的に言うとこういう構造でできた
export default function Page() {
return (
<div>
<div className="h-96 w-40 overflow-scroll bg-slate-2 p-4">
{superLongSentense}
<End />
</div>
<Confirmation />
</div>
);
}
export const End = () => {
const setAtom = useSetAtom(isReadAllAtom);
const { ref, inView } = useInView();
useEffect(() => {
if (inView) setAtom(true);
}, [inView, setAtom]);
return <div ref={ref} />;
};
export const Confirmation = () => {
const isReadAll = useAtomValue(isReadAllAtom);
const id = useId();
return (
<div>
<input id={id} type="checkbox" disabled={!isReadAll} />
<label htmlFor={id}>全部読んだ?</label>
</div>
);
};
ついでにIntersection Observer APIについて読もう
交差オブザーバー API (Intersection Observer API) は、ターゲットとなる要素が、祖先要素または文書の最上位のビューポートと交差する変化を非同期的に監視する方法を提供します。
うむ
ビューポートの中で現在見えている部分を視覚的ビューポートと呼んでいます。これは、ユーザーがピンチ操作により拡大縮小しているときなど、レイアウトビューポートより小さくなることがあります。レイアウトビューポート (en-US)は変わりませんが、視覚的ビューポートはより小さくなります。
ビューポートにも階層があるな
交差情報 (Intersection information) についての情報は次の理由から必要とされています。
- ページがスクロールした際の画像やその他のコンテンツの遅延読み込み。
- 「無限スクロール」をするウェブサイトを実装し、スクロールに従って次々とコンテンツを読み込んで、ユーザーがページの切り替えをせずに済むようにすること。
- 広告費を計算するための広告が表示されたかどうかのレポート。
- ユーザーが結果を見るかどうかで、タスクを実行するかどうか、アニメーションを処理するかどうかを決定すること。
たくさん使い道があるねー
以前は、要素同士の交差の検出を実装するには、イベントハンドラーやループで Element.getBoundingClientRect() などのメソッドを呼び出し、影響を受けるすべての要素について必要な情報を蓄積していました。このコードはすべてメインスレッドで実行されるため、これらのうち 1 つでもあればパフォーマンスの問題を引き起こす可能性があります。サイトでこのような検出が大量に行われると、まったく醜くなる可能性があります。
こういう計算の感覚、今はパッとは理解できない、悔しい...
「メインスレッドで実行されるため、これらのうち 1 つでもあればパフォーマンスの問題を引き起こす可能性があります」を字面では理解できるけど、何もないところからこれを発想するポテンシャルが今の自分にはない
交差オブザーバー API では、監視したい要素が他の要素(またはビューポート)に入ったり出たりしたとき、あるいは両者が交差する量が要求された量だけ変化したときに実行されるコールバック関数をコードに登録することができます。
交差量を表現できるんだな
交差オブザーバー API は、重複したピクセルの正確な数や、それがどのピクセルであるかを具体的に示すことはできません。しかし、「N % 前後のどこかで交差していたら、何かをする必要がある」という、より一般的な利用法はカバーします。
なるほど、ピクセルではなくてパーセンテージなのか
ターゲットが IntersectionObserver に指定された閾値を満たす度にコールバックが呼び出されます
なるほど
閾値のリスト内のそれぞれの項目は、通過した閾値を説明する IntersectionObserverEntry オブジェクトです。つまり、それぞれの項目は指定された要素がルート要素とどれだけ交差したのか、要素が交差したと言えるのかどうか、推移が発生した方向を示します。
細かい情報はentryに詰まってるのね