generated at
Scrapboxで任意の文字にcursorを移動させる
発見したのでメモするtakker
Thanks yuta0801 !

コード及び解説

基本的には、 mousedown mouseup のペアをMouseEventで発行すれば移動できる
click だとうまく行かない
mouse buttonが押されて離された後に発行されるのが原因?
MouseEvent() clientX , clientX に移動先文字の座標を入れる
入れないと常に .c-0 に飛ぶようになる
誤動作を防ぐため、文字の高さの中間位を押すように clientY を調節する
調節しないと一つ上の行を選択してしまうことがある
必ず mouseup も発行する
これを発行しなくても一見うまく行くように見えるが、ほんの少しmouseを動かすと選択範囲がいきなり現れる現象が起きる
おそらく「mouse buttonを離していない=文字列を選択中である」と解釈されるからではないか?

1. 行 id n 文字目にcursorを移動させる
リンクやcode block, 動画や画像の埋め込みがない行でのみ正常に動く
↑があると、文字をクリックできない

DOMを取得
js
const char = document.getElementById(id).getElementsByClassName(`c-${n}`)[0];
取得した文字の左上の座標を取得する
js
const {left, top, height} = headChar.getBoundingClientRect();

mouseを押すMouseEventを発行する
js
const mouseOptions = { button: 0, clientX: left, clientY: top + height / 2, bubbles: true, cancelable: true, view: window };
js
char.dispatchEvent(new MouseEvent("mousedown", mouseOptions));

mouse buttonを離すeventを発行する
js
char.dispatchEvent(new MouseEvent("mouseup", mouseOptions));

2. 任意の行の末尾にcursorを移動する
リンクやcode block、画像がある行でもつかえる
動画があっても使えるはず

id span.text を取得する
js
const line = document.getElementById(id).getElementsByClassName('text')[0];
span.text の座標を取得する
js
const {right, top, height} = line.getBoundingClientRect();
span.text の右端をclickするよう設定する
js
const mouseOptions = { button: 0, clientX: right, clientY: top + height/2, bubbles: true, cancelable: true, shiftKey: shiftKey, ctrlKey: ctrlKey, altKey: altKey, view: window };
あとは1.と同じ
js
line.dispatchEvent(new MouseEvent("mousedown", mouseOptions)); line.dispatchEvent(new MouseEvent("mouseup", mouseOptions));


#2020-11-24 01:08:18