LoginSignup

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

矢印キーでリスト内移動をしたい

解決したいこと

Go言語でタスク管理のwebサービスを開発しています。
その中で、以下のように最近取り組んだタスクのリストを表示する機能があります。
スクリーンショット 2022-10-04 18.49.00.jpg

このリスト内を矢印キーを使ってカーソル移動できるようにしたいです。
初歩的な内容で申し訳ないのですが、ご教示お願いいたします。

発生している問題

以下の{{range .Tasks}}の中にあるliをどうにかしたいです。

{{define "workspace_section"}}
<section class="workspace">
  <div class="bg-black cancel"></div>
  <div class="workspace__content">
    <h3>TASKS</h3>
    <div class="scroll-content">
      <ul>

        <!-- ここのリストを矢印キーで移動できるようにしたい -->
        {{range .Tasks}}
        <li class="pointer">
          <span class="task-title">{{.Title}}</span> 
          <span class="category-color-span task-color-{{.ID}}">
            <span class="color-span"></span>
            <span class="category">{{.Category.Name}}</span>
            <span class="hidden">{{.ID}}:{{.Category.Color.Status}}:{{.Category.Color.ID}}/</span>
          </span>
        </li>
        {{end}}
        <!-- ここまで -->

      </ul>
    </div>
  </div>
</section>
{{end}}

チャレンジしたこと

jQueryを使って、liタグのフォーカスをいじってどうにかできるかなと思ってチャレンジしてみたのですが、aタグとかじゃないとできないっぽく断念。
vueを使った方法を考えてみましたが、Goからjson形式でフロントに渡す方法がわからず断念したという感じです…。

初歩的な内容で申し訳ありませんが、ご教示お願いいたします!

0

2Answer

あくまでli要素に対してフォーカスを与えて矢印キーで移動したいのであれば、こんな方法はどうでしょう。

sample.html
<style>
li {
  cursor: pointer;
  caret-color: transparent;
}
</style>

<ul>
  <li>test1</li>
  <li>test2</li>
  <li>test3</li>
  <li>test4</li>
  <li>test5</li>
  <li>test6</li>
  <li>test7</li>
  <li>test8</li>
</ul>

<script>
'use strict';
const li = document.querySelectorAll('ul li');

const keyAssign = {
  ArrowRight: 1,
  ArrowDown: 1,
  ArrowLeft: -1,
  ArrowUp: -1
};

let currentIndex = 0;

li.forEach((e, i) => {
  e.contentEditable = 'true';
  e.dataset.b = e.innerHTML;
  e.addEventListener('input', () => e.innerHTML = e.dataset.b);
  e.addEventListener('click', () => clickElement(e));
  e.addEventListener('mouseover', () => li[currentIndex = i].focus());
  e.addEventListener('mouseout', () => {
    e.blur();
    currentIndex = -1;
  });
});
li[currentIndex].focus();

document.addEventListener('keydown', event => {
  if (Object.keys(keyAssign).includes(event.key)) {
    if (currentIndex === -1 && keyAssign[event.key] === -1) {
      currentIndex = 0;
    }
    currentIndex += keyAssign[event.key];
    currentIndex = (currentIndex + li.length) % li.length;
    li[currentIndex].focus();
  }
  else if (event.key === 'Enter' && currentIndex >= 0) {
    clickElement(li[currentIndex]);
  }
});

const clickElement = e => {
  alert(`${e.textContent} 選択時の操作`);
};
</script>
0

Your answer might help someone💌