Skip to content

Instantly share code, notes, and snippets.

@think49
Last active February 9, 2023 17:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save think49/57e3e371fe050bb3ae3a2cc9c6482a87 to your computer and use it in GitHub Desktop.
Save think49/57e3e371fe050bb3ae3a2cc9c6482a87 to your computer and use it in GitHub Desktop.
InputEvent#isComposing とIME有効/無効の検出

IME有効/無効の検出

CompositionEvent

CompositionEvent はIMEモードが有効の状態で文字列入力時を検出するイベントです。 IMEモード切替を検出しているわけではない為、[半角/全角] キーの検出は出来ません。

イベントタイプ 実行タイミング
compositionstart IMEモード有効、変換未確定で入力開始時
compositionupdate IMEモード有効、変換未確定で入力更新時
compositionend IMEモード有効、変換未確定で入力終了時 (本イベント発生時、はIMEモードは有効のまま)

InputEvent#isComposing

InputEvent#isComposingCompositionEvent と連動しており、ほぼIME有効状態を表すものとなっています。

  1. compositionstart: true (IME有効)
  2. compositionupdate: true (IME有効)
  3. compositionend: false (IME有効)

compositionend だけ、IME有効状態と合致しませんが、次回入力時の compositionstart でIME有効状態として扱える為、概ね、要件を満たします。 ただし、IE11, Safari が未対応です。

InputEvent#isComposing をエミュレートする

幸い、IE11, Safari は CompositionEvent をサポートしている為、3つのイベントを監視すれば、InputEvent#isComposing と同等のステータスを得ることが出来ます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>IME有効/無効の検出</title>
<style>
pre {
background-color: #ccc;
color: black;
}
</style>
</head>
<body>
<p>last event.type = <span id="last-event-type"></span></p>
<p>last CompositionEvent = <span id="last-composition-event"></span></p>
<p>last isComposing = <span id="last-is-composing"></span></p>
<p>last isComposing(emulated) = <span id="last-emulated-is-composing"></span></p>
<input type="text">
<pre><code></code></pre>
<script>
'use strict';
function handleCompositionEvent (event) {
const type = event.type;
const isComposing = this.isComposing = type !== 'compositionend';
document.getElementById('last-event-type').textContent = document.getElementById('last-composition-event').textContent = type;
document.getElementById('last-emulated-is-composing').textContent = isComposing;
}
function handleInput (event) {
const isComposing = this.compositionListener.isComposing;
const type = event.type;
// console.log(event.type);
document.getElementById('last-event-type').textContent = type;
document.getElementById('last-is-composing').textContent = event.isComposing;
document.getElementById('last-emulated-is-composing').textContent = isComposing;
const code = document.querySelector('pre>code');
code.appendChild(document.createTextNode((code.firstChild ? '\n' : '') + ['type = ' + type, 'isComposing = '+event.isComposing, 'isComposing(emulated) = '+isComposing]))
}
const input = document.querySelector('input'),
compositionListener = {isComposing: false, handleEvent: handleCompositionEvent},
inputListener = {compositionListener: compositionListener, handleEvent: handleInput},
entries = [
['input', inputListener],
['keydown', inputListener],
['keyup', inputListener],
['compositionstart',compositionListener],
['compositionupdate',compositionListener],
['compositionend',compositionListener]
];
for (let i = 0, len = entries.length; i < len; ++i) {
const entry = entries[i];
input.addEventListener(entry[0], entry[1], false);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment