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

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

新規登録して質問してみよう
ただいま回答率
85.45%
変数

変数は、プログラミングにおいて値や文字列などのデータを保持できる仕組みを指します。自由に名前を付けることができるため、管理しやすくなるのが特徴です。プログラムで変数の宣言を行い、値を代入して利用。保持したデータが通用する範囲でローカル変数とグローバル変数に分けられます。

JavaScript

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

Q&A

解決済

3回答

2836閲覧

変数に最初に格納した値を維持したい

rei78087487

総合スコア12

変数

変数は、プログラミングにおいて値や文字列などのデータを保持できる仕組みを指します。自由に名前を付けることができるため、管理しやすくなるのが特徴です。プログラムで変数の宣言を行い、値を代入して利用。保持したデータが通用する範囲でローカル変数とグローバル変数に分けられます。

JavaScript

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

0グッド

0クリップ

投稿2021/08/02 07:49

編集2021/08/03 05:41

概要:

前回の質問の内容と重複しますが下記ソースコードは、
・デフォルト値のテキストエリア幅は157
・テキストエリア幅はの縮小はデフォルト値以下にはならない
・文字入力数に応じてテキストエリアが拡大・縮小する

やりたいこと:

・最初に取得したclientWidthの値(157)を取得して維持するようにしたい。

下記の様に変数に要素の幅を取得した値を格納する。
let hoge = element.clientWidth;  element→テキストエリア
上記要素の幅は文字の入力数に応じて可変する。
その為、clientWidthの値は常に変化する。

・テキストエリア幅デフォルト値の部分を、最初に自分がテキストエリア右下にて拡大・縮小した値になる様にしたい。
ただし入力文字数を減らした際の縮小はデフォルト値以下になるようにする。←訂正: テキストエリア『右下』で拡大・縮小した値が最小値 
それ以外は変わらない。

試してみたこと:

・constを使用することで値を変化させないようにしたが、エラーが出た(あくまで変数を固定するもので値は固定するわけではない)

・静的変数static(値を維持する変数)について調べ、それを使用してみようと試みたが、そもそも値を維持する意味合いが認識違いであった。
※ここでの値を維持するとは、変数の処理後、値はリセットされるが、値をリセットせずに維持し続けるという意味合い

・下記は最初に取得したテキストエリア幅を基準に処理を切り替えるというのを構想していた。
testであらかじめテキストエリア幅の状態を維持。
最初のテキストエリア幅(157)を超えたら処理を切り替える

横幅取得
test = t.clientWidth;

dummyElement.style.width = dummyElement.scrollWidth + test + "px";
if文にて条件式を追加(テキストエリア幅(157))
if (isDummyobserve && t.clientWidth < dummyElement.scrollWidth) {

dummyElement.style.width = dummyElement.scrollWidth + "px";

Math.min(observeElement.scrollWidth, dummyElement.scrollWidth),minWidth) + "px";
↓変更
Math.min(observeElement.scrollWidth, dummyElement.scrollWidth) + "px";
}

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

全体ソースコード:

https://codepen.io/mio-rei/pen/OJmEoPZ?editors=1111

ソースコード:

JavaScript

1 element.oninput = (e) => { 2 let t = e.target; 3 4 /********** 追加ここから **********/ 5 // ダミーテキストエリアに文字を移植 6 dummyElement.textContent = t.value; 7 // 幅を一旦0にする 8 dummyElement.style.width = 0; 9 if (t.value.length == 0) { 10 // 文字がなくなったらテキストエリアも消すようにしています。 11 // 別に消さなくていいなら削除してください 12 t.remove(); 13 } else { 14 // observeフラグ等をセット 15 isDummyobserve = true; 16 observeElement = t; 17 test = t.clientWidth; 18 } 19 /********** ここまで **********/ 20 21 if (t.nodeName != "TEXTAREA") return; 22 23 /********** 変更ここから**********/ 24 const widthBoundary = 25 element.clientWidth - (t.getBoundingClientRect().left - cRect().left); 26 if (widthBoundary > t.scrollWidth + 16) { 27 //if (element.clientWidth - (t.getBoundingClientRect().left - cRect().left) - 0.5 >= t.scrollWidth) { 28 /********** ここまで **********/ 29 t.style.width = "auto"; 30 t.style.whiteSpace = "nowrap"; 31 t.style.width = t.scrollWidth + "px"; 32 } else { 33 console.log("規定値を超えました"); 34 t.style.whiteSpace = "normal"; 35 /********** 変更ここから**********/ 36 t.style.width = widthBoundary + "px"; 37 /********** ここまで **********/ 38 } 39 40 t.style.height = "auto"; 41 t.style.height = t.scrollHeight + "px"; 42 }; 43 44 45 46const dummyElement = document.querySelector("#dummy"); 47const minWidth = 157; 48let observeElement = null; 49let isDummyobserve = false; 50let test = ""; 51 52const observer = new MutationObserver(() => { 53 if (isDummyobserve) { 54 // ダミーの幅をセット(その前の幅は必ず0にしているので、scrollWidthがセットされる) 55 dummyElement.style.width = dummyElement.scrollWidth + "px"; 56 // ダミーと本当のテキストエリアの幅のうち小さい方を採用 57 // ただし、minWidthよりは大きくする 58 observeElement.style.width = 59 Math.max( 60 Math.min(observeElement.scrollWidth, dummyElement.scrollWidth), 61 minWidth 62 ) + "px"; 63 console.log(test); 64 }

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

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

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

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

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

maisumakun

2021/08/02 08:11 編集

> 最初に取得したclientWidthの値(157)を取得して維持するようにしたい。 現状のコードは「そうなるように実装したつもりだけどうまく行かない」のか「そうするための実装がわからず止まっている」状態の、どちらでしょうか?
rei78087487

2021/08/03 00:22

回答ありがとうございます。 現状としましては「そうするための実装がわからず止まっている」になります。 何卒ご教示頂きたくお願い致します。
BeatStar

2021/08/03 02:13

> constを使用することで値を変化させないようにしたが、エラーが出た エラーが出たならメッセージぐらい読みましょう。 > 現状としましては「そうするための実装がわからず止まっている」になります。 意図がはっきりとしませんが、 『変数testの値が刻々と変わるが、最初の値を保持して使いたい』でいいのでしょうか。 もしそうなら、『別の変数に取っておく』でいいのでは?
Lhankor_Mhy

2021/08/03 02:46

「変数の処理後、値はリセットされる」とは、具体的にはご提示のコードで言うとどこですか?
rei78087487

2021/08/03 02:50

回答ありがとうございます。 静的変数というものを調べていく中での情報になりますので、提示したコードとは関係ありません。 今回の内容にマッチした内容かと思いましたが、実際に調べていく中で違っていたのでその内容記載しました。 宜しくお願い致します。
Lhankor_Mhy

2021/08/03 03:10

ちょっと質問の内容が呑み込めていないのですが、再代入自体は禁止しないが、再代入しても値が変わらないようにしたい、というような話でしょうか?
rei78087487

2021/08/03 04:25

もし可能ならばその方法でも問題ありません。 質問した内容としましてはBeatStarさんに記載して頂いた、『変数testの値が刻々と変わるが、最初の値を保持して使いたい』という事になります。
Lhankor_Mhy

2021/08/03 04:28

const では何がダメなのでしょうか?
rei78087487

2021/08/03 04:34

constだとエラーがでます。 エラーを無視して動くならばまだ良いのですがエラー後の、後の処理は出来なくなりますので結果できませんでした。 質問内容の「試してみた事」に記載している内容は下記リンクからのものになります。 https://scrapbox.io/discordjs-japan/const%E3%81%AF%E5%A4%89%E6%95%B0%E3%82%92%E5%9B%BA%E5%AE%9A%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE%E3%81%A7%E5%80%A4%E3%81%AF%E5%9B%BA%E5%AE%9A%E3%81%97%E3%81%AA%E3%81%84
Lhankor_Mhy

2021/08/03 04:36

再代入しているからエラーになるのでは。 最初の値を保持したいならば、再代入しようとすることが間違っているように思えます。 (再代入が成功するということは、値が変化するということです)
rei78087487

2021/08/03 05:56

回答ありがとうございます。 正に現在悩んでいるところなのですが、 例えば、変数testにテキストエリア幅を取得します。 let test = element.t.clinentWidth element →テキストエリア 変数testにはテキストエリア幅の値が入っています。(この時点で157とします) この値が固定されていれば問題無いのですが、このテキストエリアは文字の入力数に応じて拡大・縮小します(全体ソースコード参照) 文字数によって可変するので、常に変数testの値が変動します。 上記全体ソースコードは、 ・ダブルクリックでテキストエリア作成(幅157) ・文字数に応じてテキストエリア幅が拡大・縮小する ・最小値は157に設定されている ※この場合だと、テキストエリアの『右下』をドラッグして拡大・縮小しても、文字を一文字でも入れたら幅が157に戻ってしまいます。 やりたいことは、 ・テキストエリアの『右下』ドラッグで拡大・縮小したサイズを維持した状態で文字入力がしたい(ここでは320に設定) ・拡大・縮小イベントは変わらない。 ・最小値は320 clientWidthで値を取得しないことにはテキストエリアの『右下』ドラッグで拡大・縮小したサイズを維持した状態の値は取得できません。 でも、clietntWdithの値は可変する。 簡略的になりますが、最初の値(157 or 320)を超えたら、拡大・縮小をイベントを行う。 という事をしたいです。 その為に最初の値を取得したいという事で質問させて頂きました。 長文失礼しました。 ご教示お願い致します。
Lhankor_Mhy

2021/08/03 06:36

> 文字数によって可変するので、常に変数testの値が変動します そこがよくわからないのですが、再代入しなければいいのでは、と思ってしまいます。 element.t.clinentWidth の値が拡大縮小によって変動するのは分かるのですが、test が変動するのは element.t.clinentWidth の値を再代入した時のみですよね? 再代入するのはなぜですか?
rei78087487

2021/08/06 00:30

回答ありがとうございます。 確かに、今回の場合だと変数testに何度も値を代入しています。 下記のコードは文字入力する度に値が代入されているので、値が常に変わるのは当然でした。 そもそも値を取得する箇所が間違っていました。 理解が追い付いて行かず何度も回答させてしまったこと、申し訳ございません。 本当にありがとうございます。 element.oninput = (e) => { let t = e.target; /********** 追加ここから **********/ // ダミーテキストエリアに文字を移植 dummyElement.textContent = t.value; // 幅を一旦0にする dummyElement.style.width = 0; if (t.value.length == 0) { // 文字がなくなったらテキストエリアも消すようにしています。 // 別に消さなくていいなら削除してください t.remove(); } else { // observeフラグ等をセット isDummyobserve = true; observeElement = t; test = t.clientWidth; ←oninputイベントにより毎回、値が変化する。 }
Lhankor_Mhy

2021/08/06 00:59

ご解決されて何よりです。 お手数ですが、自己解決の処理をお願いします。
guest

回答3

0

んー、もしかすると私の解釈ミスの可能性もあるので、話半分で。

でも一応発想はどれでも同じだと思うので。

まず、プログラミングは置いといて、『現実世界でならどうするか』を考えてみてください。

あなたは両手で幅を表現する作業を一日3回、それを三日続けることになりました。 (幼い子がよくやる、「僕のこと、どれくらい好き? これくらい?」みたいなアレ) ただし条件として、長さは前回の最後にやった長さを復元するとし、 初期値は10mm とします。 ある人(Aさん)が『後10mm長くして』というように指示を出します。 そういう指示があればその分、増減します。 『初期値に戻して』と言われたら初期値である10mmに戻します。

というような処理をするとしたらどうしますか?

私なら、初期値をノートかどこかに、

初期値 = 10mmと書いておく。

それと、現在の値も 現在の長さ = 10mm と書いておく。

つまり、ノートなりに

初期値=10mm 現在の長さ=10mm

のように『個別に書いておく』。

で、『14mm長くして』と言われたら、現在の値10mm に +14mmした
24mmにします。
記録を残しておくために、ノートに書いた『現在の長さ』を10mmから24mmに書き換える。

『あ、やっぱり初期値に戻して』と言われたら、『現在の長さ』を24mmから10mmに書き直して10mmの長さ分手を開く。

で、一回分の処理が終了し、次回はこの『現在の長さ』を復元する。

…のようにやりますね。

今回の例は意味不明ですが、イメージとして考えてください。

初期値で元に戻すのではなく、『一個前の値で』やる場合も発想自体は同じです。
単に『初期値』ではなく『一つ前の値』とタイトルが違っていて、
『一つ前の値』も刻々と書き変わる。
ということが違うだけです。

プログラミングでは『一時的な記録としてノートかなんかに書く』はできません
(できるにはできるが、効率が悪すぎる)
ので、『変数』を使いましょう。ってことです。

そう考えると、『初期値用』と『現在の値』はそれぞれ別の変数として考えることができますね。

こうすれば、『初期値に戻す』とか『初期値より小さければ』とかの処理が可能になります。

投稿2021/08/03 05:25

編集2021/08/03 05:28
BeatStar

総合スコア4958

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

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

rei78087487

2021/08/06 01:00

前回に引き続き、回答頂き本当にありがとうございます。 前述にLhankor_Mhyさんから再代入の話しをして頂いて、無事解決できました。 私の理解が追い付いて行かずにお手間を取らせたこと申し訳ございません。 今一度ご教示頂きたいのですが、前述して頂いた『別の変数に取っておく』の事でお聞きしたいです。 これも再代入の話を聞いて何とかわかりかけているのですが、 例えば変数test = t.clientWidth(値=157)だとします。 この値は先程の様に変化しますが、この変化する前の値を別の『別の変数に取っておく』ということは、 変数 const fixed = test とすれば、fixedの値は157になる。 つまり、 fixed = test = t.clientWidthという事になる。 最初の値をあらかじめfixedに移しておくことにより、最初の値が使用出来るという認識で宜しいでしょうか? ですが、これでもoniunputイベントの中に値を取得する形だと fixed = test = t.clietnWidthの形になっているので、fixedの値も常に変化してしまうことになるので、oninputイベントの中で値を取得してはいけない。 以上の様にまとめましたが、認識は正しいでしょうか? 宜しくお願い致します。 element.oninput = (e) => { let t = e.target; /********** 追加ここから **********/ // ダミーテキストエリアに文字を移植 dummyElement.textContent = t.value; // 幅を一旦0にする dummyElement.style.width = 0; if (t.value.length == 0) { // 文字がなくなったらテキストエリアも消すようにしています。 // 別に消さなくていいなら削除してください t.remove(); } else { // observeフラグ等をセット isDummyobserve = true; observeElement = t; test = t.clientWidth; ←ここに入力すると、文字入力の度に値が更新される }
guest

0

自己解決

変数に最初に格納した値を維持したい。

結果としては変数に何度も値を再代入していたことが原因だった。
値を取得する箇所が文字を入力する度に再代入されるので、毎回、値が更新される状態になっていた。
記述箇所を変更したことにより解決した。

ソースコード:

JavaScript

1const minWidth = ''; ←グローバル変数を作成 2 3// 文字を入力するとイベントが起きる 4element.oninput = (e) => { 5 let t = e.target; 6 7 // ダミーテキストエリアに文字を移植 8 dummyElement.textContent = t.value; 9 // 幅を一旦0にする 10 dummyElement.style.width = 0; 11 if (t.value.length == 0) { 12 // 文字がなくなったらテキストエリアも消すようにしています。 13 // 別に消さなくていいなら削除してください 14 t.remove(); 15 } else { 16 // observeフラグ等をセット 17 isDummyobserve = true; 18 observeElement = t; 19 minWidth = t.clientWidth; ←ここが毎回、文字を入力する度に値が更新されてしまう。 20 } 21    ~~~~~~~~~

oninputイベントの中に該当の変数を記述して値を取得していた。
だが、これだと文字を入力する度に値が変化してしまう(ここでのテキストエリアは文字を入力する度に拡大・縮小するのでテキストエリアの幅は固定ではない)

JavaScript

1// テキストエリアをクリックすると起きるイベント 2// アクティブ 3 const click = (e) => { 4 const iterable = document.querySelectorAll('textarea'); 5 const imgmap = document.querySelectorAll('.graphics'); 6 const square = document.querySelectorAll('.lt, .rt, .rb, .lb'); 7 8 let t = e.target; 9 if(t.nodeName != 'TEXTAREA' && !t.classList.contains('graphics') && 10 !t.classList.contains('canvas-parent')) return; 11 minWidth = t.clientWidth;  ← 記述箇所をこちらに変更した。 12 for (const elmTa of iterable) { 13 elmTa.classList.remove('active'); 14 } 15 for (const image of imgmap) { 16 image.classList.remove('active'); 17 } 18 for (const four of square) { 19 four.style.display = 'none'; 20 } 21 t.classList.add('active'); 22 for (const taChild of Array.from(t.parentNode.children)) { 23 taChild.style.display = 'block'; 24 }

アクティブイベントは上記には記載されていないが全体のソースコードの一部にあるイベント。
こちらに記述箇所を変えることにより、テキストエリアをクリックした時に取得した値を使用する事ができる。
例えば、クリックして変数の値が(157)だった場合、この変数をoniputイベント内で使用しても変数の値は変わることはない。
イベントが起きている箇所で値を取得する為。

・グローバル変数を作成 const minWidth = '';
・値をアクティブイベントで取得 minWidth = t.clientWidth(tはテキストエリア)
・取得した値の変数minWidthをoninputイベント、その他で使用しても値は変化しない)

投稿2021/08/07 22:55

rei78087487

総合スコア12

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

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

0

テキストエリアの幅を固定したいのであればcssの領分かと思います。

css

1.canvas-parent textarea{ 2 width: 157px !important; 3 /*resize: vertical; 縦方向のみリサイズ可など*/ 4}

投稿2021/08/02 09:04

webgoto

総合スコア1293

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問