質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

JavaScriptでkeyupが発火しないときがある

tobytoby
tobytoby

総合スコア1

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

2回答

0グッド

0クリップ

582閲覧

投稿2023/01/25 01:01

編集2023/01/25 01:39

前提

JavaScriptのkeydown、keyupでキーボードの押下状態を監視しているのですが、
keyupが発火しないときがあります。

下記のコードはそれを確認するためのサンプルで、
押している状態のキーを画面に表示するというものです。

サンプルのソースコード

JavaScript

1var a = new Object(); 2window.addEventListener("load", function() { 3 window.addEventListener("keydown", function(e) { 4 a[e.key] = 1; 5 }); 6 window.addEventListener("keyup", function(e) { 7 delete a[e.key]; 8 }); 9 setInterval(function() { 10 document.body.innerHTML = Object.keys(a).join(" , "); 11 }, 50); 12});

試したこと

上記のコードで、
キーボードでガチャガチャとキーを押していると、たまにkeupが発火せず、
画面上に押下状態のキーとして表示され続けるものが現れます。

そのキーはABCD,,,のような文字を入力するキーで発生して、
Enterや矢印のキーなどでは発生しないように思います。

また、keyupが発火しなかったキー(以下、該当キー)は、
それ以外のキーをガチャガチャ押していると、
該当キーを押していないのにkeyupが発火することがあります。

他に試したこととして、
addEventListenerの第3引数にも色々オプションを付けてみましたが、
特に解決できませんでした。

これはブラウザの特性上どうしようもないものなのか、
それとも解決策があるのか、教えていただけますと幸いです。
(私の環境はWin11でChromeを使用しています)

よろしくお願いします。

追記:確認したOSやブラウザ

ご指摘いただき他の環境で確認したところ、結果は下記のとおりでした。

▽再現されたPC
デスクトップPC Windows11(64bit) Chrome、Edge
ノートPC  Windows11(64bit) Chrome、Edge

▽問題無かったPC
ノートPC Windows10(64bit) Chrome、Edge
MacBook Ventura13.1 Chrome、Safari
RaspberryPi RaspberryPiOS Chromium

一部の環境下で発生しているようです。
再現されたPCでは別メーカーのキーボードに変えても発生しました。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

m.ts10806

2023/01/25 01:10

確認したブラウザやOSなど環境情報も提示してください。 また他のブラウザでも確認してみた結果も追記してください。
tobytoby

2023/01/25 01:39

ご回答いただきありがとうございます。 ご指摘いただいた内容を元に、他のPCでも試した結果を追記しました。
think49

2023/01/25 10:50 編集

コード上でいくつか気になる点はありますが、まずは再現条件を特定するのが先決だと思います。 「キーボードでガチャガチャとキーを押している」は再現条件ではありませんので、「どのキーどの順番で押すと~になる」など、きちんと特定する必要があります。 一応、再現はできて原因らしきものにあたりをつけられましたが、質問としてはあまりよくありません…。 私が確認した再現条件と本質問の再現条件が同じである保証がありませんので。
tobytoby

2023/01/25 13:23

ご回答いただきありがとうございます。 また、ご指摘いただき誠にありがとうございます。 再現条件なのですが、恐れながら私の知識と調査不足で見つけられておりません... 試しに約0.5秒間隔でキーを 左下の[z]キーなどから右方向に順番に1つずつ押していってみましたが、 その操作でもkeyupが発生しない現象が起こりました。 (50回押して1回程度の確率) しかし発生したときのキーやタイミングについては再現性はなく、 同じ条件で実行しても同じ結果にはなりません。 ただ、上記の操作の中でkeydownとkeyupの動きを見ていると、 keyupが発生しない現象が発生したタイミングで、 「過去にkeyupが発生しない現象が発生したときに押していたキー」のkeyupが発火しているようでした。 さらに、「keyupが発生しない現象」が発生した後にページをリロードしても、 再度「keyupが発生しない現象」が発生したタイミングで 「リロード前のページで本現象が発生したときに押していたキー」のkeyupが発火したので、 ページをまたいで現象が発生しているようでした。 (わかりにくい文章で申し訳ございません) IMEがONのときは「keyupが発生しない現象」が起きたタイミングで 半角全角のkeyupが発火することがあるようですし、よくわからない状況です...
think49

2023/01/28 06:53

@tobytoby さん 書かれた再現条件はよくわかりませんが、OS側でキーボード入力が検知されているか確認し、JavaScriptコードで検知したイベントと比較すると良いかもしれません。 https://www.google.com/search?q=%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89+%E7%9B%A3%E8%A6%96+windows JavaScript側の問題なのか、キーボードのハードウェア上の問題なのか、OSの問題なのか、様々な原因がある気がします。
tobytoby

2023/01/28 15:25

ご回答いただきありがとうございます! ご提案いただいたものを参考に、C#でキーボードのイベントを監視しました。 その結果、問題が起こっているPCのChrome、Edgeで、 JavaScriptで検知したkeydown,keyupと合致したものがC#でも検知されました。 (問題が発生したときに別のキーのkeyupが発火するのも同じ) IE11でも試してみたところ、Chrome,Edgeと同様にkeyupの問題が発生しました。 さらに、スクリーンキーボードでも試してみましたが結果は同様で、keyupの問題が発生します。 一方で、Excelなどをアクティブウインドウにしてキーボードを押す場合は、 keyupが発火しないような問題は起こらず、 正しくkeydown,keyupが検知されていました。 また、C#に埋め込んだWebView2でも問題なくkeyupが発火していました。 これらから考えると、原因はOSなどにあり、 JavaScriptでは手に負えない範囲なのかもしれませんね... (また、古いWin10のPCを引っ張り出してきてChromeで試してみましたが、 そちらでは問題無いようでした。 そしてWin11にしようとしましたがスペック不足でできませんでした)
tobytoby

2023/01/28 16:34 編集

追伸で、↑の古いWin10のPCについてですが、 Windowsアップデート後に確認したところ症状が発生しました。 (アップデート前後共にChromeのビルドは109) そのため、もしかするとWindowsアップデートの何かが影響しているのかもしれません。 ▽追記 しかしアップデートされたものをアンインストールしても症状は発生したので、 Windowsアップデートは関係無いかも... (KB5019959のアンインストールはエラーが起きて失敗したので、それが原因かは不明)

回答2

1

「keyupが発火しない状況」はありうるので、その観点で回答します。

コードの修正

まず、下記問題を解決する為、コードを修正します。

  • new Object のkeyは定義済みのものがある
  • setInterval で50ms周期で監視する為、50ms以内にkeydown->keyupすると取りこぼしが発生する
  • innerHTML でkey情報を表示している為、<>& が特殊文字として扱われる

PlunkerにもコードをUPしています。

html

1<!DOCTYPE html> 2<title>sample</title> 3<meta charset='utf-8'> 4<script> 5 'use strict'; 6 { 7 const listener = { 8 keys: new Set, 9 handleEvent: function (event) { 10 const keys = this.keys; 11 12 switch (event.type) { 13 case 'keydown': 14 keys.add(event.key); 15 event.currentTarget.body.textContent = [...keys]; 16 break; 17 case 'keyup': 18 keys.delete(event.key); 19 event.currentTarget.body.textContent = [...keys]; 20 break; 21 } 22 } 23 }; 24 25 document.addEventListener('keydown', listener, false); 26 document.addEventListener('keyup', listener, false); 27 } 28</script>

再現条件

下記コードに注目してください。

javascript

1document.addEventListener('keydown', listener, false); 2document.addEventListener('keyup', listener, false);

document内で発生したkeydown,keyupイベントを拾うコードですので、document外で発火したkeydown,keyupイベントは検知できません
例えば、次の方法でkeyupイベントが発火したい状況を再現できます。(keydownイベントも発火しません)

  • Google Chromeで [Ctrl] + [D] キーを押下 -> ブックマーク追加ダイアログにフォーカスが移る為、keyupが検知されない
  • Google Chromeでアドレスバー(ロケーションバー)を表示した状態で [Ctrl] + [L] キー押下 -> アドレスバーにフォーカスが移る為、keyupが検知されない

仕様通りの挙動なので、この挙動を前提に対策しておく必要があります。

  • FAQなどでユーザに説明しておく
  • blur イベント発火時に画面に出力されたキー情報をクリアする

投稿2023/01/28 05:35

編集2023/01/28 06:48
think49

総合スコア18056

tobytobyを押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

tobytoby

2023/01/28 15:39

ご回答いただき誠にありがとうございます! また、コードを修正いただきありがとうございます。 Plunkerも確認いたしました。 問題箇所の修正をしていただいた上、 モダンな記述に改めていただきありがとうございます。 大変参考になりました。 再現条件にご記載いただいた内容ですが、 keyupの問題が発生した際にはフォーカスが移っておらず、 blurのイベントも発火していないようです。 また、お送りいただいたPlunkerのコードでも、 私の2台のPCではkeyupが発火しない現象が起こりました。 色々原因を考えていると、 もしかすると私の2台のPCだけに起きている問題ではと思えてきましたので、 伝手を頼って他のPCでも現象を確認していこうと思います。 しばらく時間が空いてしまうと思いますが、 結果を改めてご報告させていただきますm(_ _)m think49様にはコードの修正や提案など色々フォローをいただき、 とても感謝しております。 こんなに親身に対応していただけるとは思ってませんでした。 本当にありがとうございます!

0

自己解決

自己解決しました。

ESET INTERNET SECURITYの「すべてのブラウザーを保護」のチェックを外したら
正しくkeyupが動作するようになりました。

セキュリティソフトが余計な制御を行っていたようです。

お騒がせしました。

投稿2023/01/31 08:32

tobytoby

総合スコア1

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。