0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

lil.guiでテキスト入力時にEnterキーでフォーカスが外れるのを防ぐ

Posted at

はじめに

 lilでテキストを入力するとき、普通に実装するとエンターキーを押すときにフォーカスが外れて不便なので、それを解消する話。

コード全文

index.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>lil focusout</title>
    <script src="https://cdn.jsdelivr.net/npm/lil-gui@0.20.0"></script>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
    <p id="string"></p>
    <script src="main.js"></script>
  </body>
</html>
style.css
html {
  font-size:62.5%;
}

* {
  box-sizing: border-box;
}

html, body {
  margin:0;
  padding:0;
}

main{
  display:grid;
  place-items:center;
  height:100dvh;
  overflow:auto; /* autoです。 */
}

p{
  font-size:1.8rem;
}
main.js
function sketch(){
  // addColorの方は日本語入力時のエンターでfocusoutしないが
  // テキストの場合はfocusoutするので不便である。
  const config = {txt:"", col:'#FF0000'};

  let elem;
  const gui = new lil.GUI();
  gui.add(config, "txt").onChange((t) => {
    document.querySelector("#string").innerText = t;
    if(elem === undefined){
      // elemにそのときのフォーカスエレメントを代入することで入力部分のDOMを扱えるようにする
      elem = document.activeElement;
      elem.addEventListener("keydown", (e) => {
        // エンターキーを押したときにフォーカスイベントが発生するようにする。
        // このイベントはフォーカスアウトの後で発生するのでフォーカスを戻すことができる。
        if(e.code === 'Enter'){
          elem.focus();
        }
      });
    }
  });

  gui.addColor(config, "col");
}

document.addEventListener("DOMContentLoaded", sketch);

普通にやった場合のlilの挙動

 lilで文字を入力する場面は、オブジェクトタイプがstringの場合と、addColorで文字入力をする場合である。addColorのボックスはなぜか文字入力の際にフォーカスが外れないようになっているが、タイプがstringの場合はなぜか、漢字変換などの際にエンターキーを押すとフォーカスが外れてしまう。

解消

 フォーカスイベントを使う。

  let elem;
  const gui = new lil.GUI();
  gui.add(config, "txt").onChange((t) => {
    document.querySelector("#string").innerText = t;
    if(elem === undefined){
      // elemにそのときのフォーカスエレメントを代入することで入力部分のDOMを扱えるようにする
      elem = document.activeElement;
      elem.addEventListener("keydown", (e) => {
        // エンターキーを押したときにフォーカスイベントが発生するようにする。
        // このイベントはフォーカスアウトの後で発生するのでフォーカスを戻すことができる。
        if(e.code === 'Enter'){
          elem.focus();
        }
      });
    }
  });

あらかじめ要素の代入先を用意しておき、文字入力の際にフォーカスエレメントの取得により入力部分のDOMを取得する。そしてその際に、Enterキーのイベントとしてフォーカスさせるイベントが発生するようにする。こうすると、フォーカスの際のフォーカスアウトの後でこれが発生するので、問題なく引き続き入力することができる。

おわりに

 ここまでお読みいただいてありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?