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

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

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

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

JavaScript

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

Q&A

解決済

1回答

1056閲覧

テキストエリアに文字を入力する際、親要素最下部(右端)まで入力したら文字数を制限して入力できなくする

rei78087487

総合スコア12

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

JavaScript

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

0グッド

1クリップ

投稿2021/07/16 07:51

やりたいこと:

幅と高さが文字数に応じて変動するテキストエリアに、親要素最下部(右端)まで入力したら文字数を制限して入力できなくする

概要:

・ダブルクリックでテキストエリアを作成。
・テキストエリアの幅と高さは文字数に応じて拡大・縮小する(テキストエリア幅については前述の質問内容になります)
・テキストエリア幅は親要素を超えようとすると自動的に折り返します。

テキストエリアの高さが親要素の最下部(右端)まで到達した時に文字数を制限できるようにしたいです。
アラートではなく、それ以降の文字が打てなくなるようにしたいです。

参考資料:

https://teratail.com/questions/207630?link=qa_related_sp
https://joyplot.com/documents/textarea-%E5%85%A5%E5%8A%9B%E8%A1%8C%E6%95%B0%E5%88%B6%E9%99%90/

様々調べてみたのですが、参考の資料はあらかじめ最大文字数が決まって文字数を制限するようになっています。

今回の条件は、
・文字入力の際、テキストエリアの高さが親要素の最下部まで来た時
・その際にテキストエリア内の最大文字数が何文字か

2番目の条件は、テキストエリアの作成位置、幅や高さが変動する為に毎回最大文字数が変わります。
なので、あらかじめ文字数が何文字まで入力できるかわかりません。
この2つの条件を元に入力制限ができると考えているのですが…

お手数ですが何卒教えて頂きたくお願い致します。

全体ソースコード:

https://codepen.io/k4a/pen/JjNEjOE?editors=1111
※前述の質問にて回答者様より頂いた引用になります。

ソースコード:

※あくまで引用を元に作成してるので、全体ソースコードと若干異なります。

JavaScript

1 element.oninput = (e) => { 2 let t = e.target; 3 dummyElement.textContent = t.value; 4 dummyElement.style.width = 0; 5 if (t.value.length > 0) { 6 isDummyobserve = true; 7 observeElement = t; 8 } 9 10 if (t.nodeName != 'TEXTAREA') return; 11 12 const widthBoundary = element.clientWidth - (t.getBoundingClientRect().left - cRect().left); 13 if (widthBoundary > t.scrollWidth + 16) { 14 t.style.width = 'auto'; 15 t.style.whiteSpace = 'nowrap'; 16 t.style.width = (t.scrollWidth) + 'px'; 17 } else { 18 console.log('規定値を超えました'); 19 t.style.whiteSpace = 'normal'; 20 t.style.width = widthBoundary + 'px'; 21 console.log(t.style.width); 22 console.log(t.value.length); 23 24 } 25 26 27 if (element.clientHeight - (t.getBoundingClientRect().top - cRect().top) > t.scrollHeight && 28 t.value > max.length) { 29 console.log('test'); 30 t.style.height = "auto"; 31 t.style.height = (t.scrollHeight) + 'px'; 32 33 } else { 34 console.log('入力不可'); 35 t.value = ''; 36 }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

今回の問題としている箇所は、
・文字入力の際、テキストエリアの高さが親要素の最下部まで来た時
・その際にテキストエリア内の最大文字数が何文字か

特に2番目の文字数の取得が問題となっている。

一番目の箇所は、
>ポイント
if (element.clientHeight - (t.getBoundingClientRect().top - cRect().top) > t.scrollHeight)
とすることで、テキストエリアの幅が親要素の最下部に到達するまで処理を行う。

2番目の箇所として
>ポイント
test.propaty = t.value.length;
ここが特に大きなポイント。
testオブジェクトにpropatyプロパティを作成。そのプロパティの中にt.value.lengthを格納する
t.value.lengthは現在のテキストエリアの文字数を取得できる。

これを行う事で、テキストリアが親要素の最下部まで来た時の最大文字数を取得する。
このpropathプロパティをsubstrメソッドで使用することで、入力制限をかけることができる。
t.value = t.value.substr(0, test.propaty);

肝となるのはプロパティにlengthの値を入れること。
if分に変数を使用すれば同じことが出来ると思うが、それだとスコープの問題によりできない。
if文で書いたtest.propaty = t.value.length;が仮に、
const test = t.value.lenghtと書いてelseで使用しても違うブロック(ローカル)スコープなので、
elseに変数testを使用する事ができない。
なのでプロパティに値を入れる事で、else文にもproptaty(t.value.length)の値を使用する事ができる。

もうひとつの疑問として、lengthプロパティは毎回文字を入力するたびに文字数の取得が変化するから、最下部のところまで来た時の文字数はわからないと思ったが、
あくまでその値はif分の条件式、
if (element.clientHeight - (t.getBoundingClientRect().top - cRect().top) > t.scrollHeight)
テキストエリアの幅が親要素の最下部に到達するまで処理を行う

までの値をプロパティに入れているのでlengthの値は随時更新されるが、プロパティに入っている値はあくまでも上記if分条件式までの値になる。

これを行う事でテキストリアエリアが親要素の最下部(右端)まできた時に入力制限をかけることができる。

全体ソースコード:
https://codepen.io/mio-rei/pen/YzVQZbL

JavaScript

1const test = {}; 2 3element.oninput = (e) => { 4 ~~~~~~~~~~~~~~省略 5 if (element.clientHeight - (t.getBoundingClientRect().top - cRect().top) > t.scrollHeight) { 6 test.propaty = t.value.length; 7 t.style.height = "auto"; 8 t.style.height = (t.scrollHeight) + 'px'; 9 10 } else if (t.value.length > test.propaty) { 11 console.log('入力不可'); 12 t.value = t.value.substr(0, test.propaty); 13 } 14 }

投稿2021/07/19 01:35

rei78087487

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rei78087487

2021/08/01 02:57

訂正: 上記内容にて、プロパティを使用した最大文字数の取得を記載しましたが、一点誤りがありましたので訂正します。 プロパティで最大文字数を取得する事で、elseブロックに取得した内容が引き継がれる →誤 グローバル変数を使用した方法で最大文字数が取得できる →正 単順に変数をグローバルで作成してから、ローカル内で値を取得すればelseブロックでも使用出来ます。 お手数おかけしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問