scrapbox:listレイアウトで、カーソルキー使ってフォーカス移動したい
やりたいこと
window.scrapbox というオブジェクトが生えており、ここから情報が取得できる
グリッドがたくさん並んでるページは scrapbox.Layout === "list" となる。
ここはタブキーでフォーカス移動ができるが、前・後にしかいけない。
ここで、カーソルキーを使って移動できるようにしたい
左:-1
右:+1
上:-グリッド数
下:-グリッド数
実現方法メモ
今フォーカスがある要素から次の要素へ移動するにはこう書ける。
code:move.js
document.activeElement.parentElement.nextElementSibling.children0.focus() // ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^
// - 今focusのあるaタグの -- 親liの - 次のliの --子要素aに `-- focus
グリッド数を出すにはどうしたらいいだろうか?
ブラウザの横幅、scrapboxの設定の2軸で制御される
単純に親要素の横幅を子要素の横幅で割って求めてみる
document.querySelector('li.page-list-item').clientWidth
これでできた
parseInt(document.querySelector('div.page-list').offsetWidth / document.querySelector('li.page-list-item').offsetWidth)
コード
code:script.js
(() => {
let onKeyDown = function(e){
if (scrapbox.Layout === "list" && e.shiftKey && e.code.substr(0, 5) === "Arrow") {
// OK
} else {
return;
}
function getGridNumber() {
return parseInt(
document.querySelector('div.page-list').offsetWidth / document.querySelector('li.page-list-item').offsetWidth
);
};
const grid = getGridNumber();
const distance = {
ArrowUp: - grid,
ArrowLeft: - 1,
ArrowRight: 1,
ArrowDown: grid
let current = document.activeElement.parentElement;
if (! current.classList.contains("page-list-item")) {
// グリッド選択状態でなければ最初のグリッドを選択
current = document.querySelector('.page-list-item');
} else if (0 < distance) {
// 進行方向(右・下)へ移動
for (let i = 0; i < distance; i++) {
current = current.nextElementSibling;
if (current === null) {
return; // 端っこ
}
}
} else {
// 逆方向(左・上)へ移動
for (let i = 0; i > distance; i--) {
current = current.previousElementSibling;
if (current === null) {
return; // 端っこ
}
}
}
current.children0.focus(); };
document.addEventListener('keydown', onKeyDown);
})();