use-cursor-observer
scrapboxのcursorを追跡し、特定のDOMの中にいる時のみなにかするHook
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.jsimport {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});
}