こんにちは
以下の3点を修正してみると、いかがでしょうか?
(1) <textarea>
の属性に wrap="off"
を追加
(2) function()
に引数 e
を追加して、 function(e)
に修正
(3) イベントハンドラの本体に、以下を追加
javascript
1 if (e.type === 'keydown' && e.keyCode === 13) {
2 const lines = e.target.value.split('\n');
3 if (lines.length === 5)
4 e.preventDefault()
5 }
以下は、ご質問にある、動くサンプルをFork して、上記の修正をしたものです。
参考になれば幸いです。
追記
ご質問に
自動で折り返した時に一行としてカウントします。
との追記がありましたので、 wrap
属性を off
にする上記の回答では、ご質問の要件を満たせていないと思われますので、上記回答は無視してください。自動折り返しされているテキストの行数カウントの方法が見つかれば、また追記します。(が、ざっと調べたところ簡単ではなさそうです。)
追記2
自動折り返しされているテキストの行数カウントの方法を調べたところ、stackoverflow に以下の記事を見つけました。
上記をもとに作成したHTMLが以下です。
html
1<!DOCTYPE html>
2<html lang="ja">
3<head>
4 <meta charset="UTF-8">
5 <title>Q213634</title>
6 <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
7 <script>
8
9 function getURLParameter(qs, name) {
10 const pattern = "[\?&]"+name+"=([^&#]*)";
11 const regex = new RegExp(pattern);
12 const res = regex.exec(qs);
13 if (res == null)
14 return "";
15 else
16 return res[1];
17 }
18
19 function getHardWrappedText() {
20 if (top.location.href !== window.location.href) return;
21
22 const frmUrl = $('iframe').get(0).contentDocument.URL;
23 if (frmUrl.indexOf('http') < 0) return;
24
25 return unescape(getURLParameter(frmUrl, 'text')).replace(/+/g,' ');
26 }
27
28 $(function(){
29 const linesCountUpdater = () => {
30 const text = getHardWrappedText();
31 if (!text) return;
32 const lines = text.split('\n');
33 $('span').text(lines.length);
34 };
35
36 $('iframe').on('load', linesCountUpdater);
37 $('textarea').on('keyup', () => { $('form').submit(); })
38 })
39 </script>
40 <style>
41 textarea { font-size: 36px; line-height: 36px; width: 200px; height: 220px; }
42 span { font-weight: bold; margin-right: 3px; }
43 </style>
44</head>
45<body>
46現在の行数:<span>0</span>行
47<form method="get" target="hidden-frame">
48 <textarea name="text" wrap="hard"></textarea>
49</form>
50<iframe name="hidden-frame" style="display:none;"></iframe>
51</body>
52</html>
53
上記をコピペして HTMLファイルを作成し、何らかのWEBサーバー(Apache, Nginx など)経由でブラウザに表示させ、テキストエリアに文字を打っていくと、自動改行するごとに、現在の行数が更新されます。
このやり方だと、ひとつ文字を打つごとにフォームをサブミットしてWEBサーバーとの往復が生じてしまうので、実用的ではなさそうですが、調べたところ私の理解ですと、テキストエリア内で自動改行されたテキストが、その見た目どおりに改行コードを含む文字列になるのは、そのテキストエリアを含むフォームがサブミットされてサーバーへ送信される時点なので、上記のコードのように、隠しiframeを使うという、トリッキーなことをしなければならないようです。