チャットアプリでよくある Shift+Enter で改行、Enter で送信する方法を調べてみると色々な方法が見つかったので、それらの中から私が決定版だと思ったものを記しておきます。
Shift+Enter で自動調整
<html>
<body>
<textarea id="foo" style="resize: none; overflow: hidden;"></textarea>
<script>
const textarea = document.getElementById("foo");
// Shift+Enter で自動調整
textarea.oninput=function(){
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
}
</script>
</body>
</html>
そもそも「Shift+Enterで改行」という設問が良くなかった。
textarea は shift の有無に関わらず Enter で改行を入力できるので、やりたいことは「垂直スクロールバーを使用せずにコンテンツをビューポート内に収めるために必要な最小の高さに調整する」ということになります。なので scrollHeight
を使います。
それだけだと高さは増える一方なので this.style.height = 'auto'
でコンテンツが削除されたら減るようにします。
input イベントを用いていることにも留意ください。コンテンツの高さを計算できるのは入力された後だからです。
Enter で送信
input される前にイベントを捕まえたいのでこちらは keydown イベントを使います。
<html>
<body>
<textarea id="foo" style="resize: none; overflow: hidden;"></textarea>
<script>
const textarea = document.getElementById("foo");
// Shift+Enter で自動調整
textarea.oninput=function(){
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
}
// Enterで送信
textarea.onkeydown=function(e) {
const isIMEComposition = e.isComposing || e.code === 229;
if (e.key === 'Enter' && !e.shiftKey && !isIMEComposition) {
console.log("Submit:", textarea.value);
}
}
</script>
</body>
</html>
Shift が押されていなくかつ日本語変換中でもないという判定を行います。isComposing
は、イベントが変換セッションの途中であることを示します。e.keyCode
の 229
は日本語変換確定時のEnterキーを表します。
以上です.