generated at
use-cursor-observer
scrapboxのcursorを追跡し、特定のDOMの中にいる時のみなにかするHook
負荷低減のために、custom-throttleで間引いている

2021-06-20
22:54:10 display: none; があるかないかの違いだけなら更新しない
2021-06-19
19:51:52 依存配列の設定をミスってた
09:10:42 依存配列を渡せるようにした
2021-06-18
15:54:58 #text-input ではなく .cursor を追跡するよう変更した
#text-input だと、cursorの動きに追随しないことがある

dependencies
script.js
import {useMemo} from '../preact@10.5.13/hooks.js'; import {useMutationObserver} from '../useMutationObserver/script.js'; import {throttle} from '../custom-throttle/script.js'; export function useCursorObserver(_callback, {delay = 100, immediate = true} = {}, deps = []) { const callback = useMemo(() => throttle(async (mutation) => { const cursor = mutation.target; // 変更点がdisplay: noneしかなければ何もしない const newCSSText = cursor.style.cssText.replace(/display: none;/, '').trim(); const oldCSSText = mutation.oldValue.replace(/display: none;/, '').trim(); if (newCSSText === oldCSSText) return; const top = parseInt(cursor.style.top); const left = parseInt(cursor.style.left); const height = parseInt(cursor.style.height); const parentRect = cursor.parentElement.getBoundingClientRect(); const cursorRect = { top: top + parentRect.top, left: left + parentRect.left, right: left + 1 + parentRect.left, bottom: top + height + parentRect.top, height, width: 1, }; const elements = document.elementsFromPoint( cursorRect.left + cursorRect.width / 2, cursorRect.top + cursorRect.height / 2 ); await _callback({cursorRect, parentRect, elements}); }, delay, {immediate}), deps); useMutationObserver([{current: document.getElementsByClassName('cursor')?.[0]}], ([mutation]) => callback(mutation), {attributes: true, attributeFilter: ['style'], attributeOldValue: true}); }