generated at
mouse pointerのいる行を取得するテスト
特定の座標から行を特定するcodeのテスト

実装
mouse pointerの取得
mousemove eventを使う
使用するproperty
offsetX
e.target のlocal座標系でのx成分
screenX
e.target のscreen座標系でのx成分
screen座標系ってなんだ?takker
clientの物理的なdesplayの左上を原点とした座標系みたい
clientX
e.target のborderを含む領域の左上を原点とした座標系
pageX
見えたい部分も含むページ全体の左上を原点とした座標系
行の移動を検知したときだけ console.log を実行する
毎回やるとすごく見にくくなる
04:01:12 このcodeで問題なさそう
js
document.addEventListener('keydown',e=>{ const {left,top} = scrapboxDOM.textInput.getBoundingClientRect(); const target = [...scrapboxDOM.lines.children].find(line =>{ const rect = line.getBoundingClientRect(); return rect.top <= top && top < rect.bottom //&& rect.left <= left && left < rect.right; // Y座標だけ範囲内であればいい }); const line = target.closest('.line'); console.log({ index:[...scrapboxDOM.lines.children].indexOf(line), line, target, }) })
document.elementFromPointで検索できそう
こんな便利なやつあったのか
js
document.addEventListener('mousemove',e=>{ const target = document.elementFromPoint(e.clientX,e.clientY); const line = target.closest('.line'); console.log({ index:[...scrapboxDOM.lines.children].indexOf(line), line, target, }) })
これだと #text-input target に入っちゃうみたい
#text-input がいる場所はどのみち行のDOMを取得できない
一旦 #text-input display: none にしたら取得できるかな?
03:47:25 できた
こうした
js
const {top,left,width,height}=scrapboxDOM.textInput.getBoundingClientRect(); const display = scrapboxDOM.textInput.style.display; scrapboxDOM.textInput.style.display='none'; const target = document.elementFromPoint(left+width/2,top+height/2); scrapboxDOM.textInput.style.display=display;
画面の表示領域から外れると target null になったりして正常に取得できない
上に別な要素が描画されていた場合も取得できない
nav barの固定表示とか
2021-03-30 09:51:17 DocumentOrShadowRoot.elementsFromPoint()なら、重なっている要素も取得できる
実験的な機能だが、主要なbrowserで実装されているので使えそう
js
{ const observer = new MutationObserver(() => { const {top, left, width, height} = scrapboxDOM.cursor.getBoundingClientRect(); const targets = document.elementsFromPoint(left + width / 2, top + height / 2); const char = targets.find(target => target.matches('span[class^="c-"]')); const line = targets.find(target => target.matches('.line')); console.log({ index: [...scrapboxDOM.lines.children].indexOf(line), char, line, }); }); observer.observe(scrapboxDOM.cursor, {attributes: true}); }
やっぱり確実に取得するために、座標計算して検索したほうが無難かなあ
でも折返し処理とかが面倒なんだよなあ
js
document.addEventListener('keydown',e=>{ if(!/Arrow/.test(e.key))return; const {top,left}=scrapboxDOM.textInput.getBoundingClientRect(); const target = document.elementFromPoint(left,top); const line = target.closest('.line'); console.log({ index:[...scrapboxDOM.lines.children].indexOf(line), line, target, }) })

#2021-03-30 09:52:52
#2020-12-11 02:46:29