🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

2回答

1758閲覧

inputの「範囲を超えた分を左右キーで表示」を、divに実装する方法

kanimiso

総合スコア5

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2019/10/06 01:55

編集2019/10/07 02:37

前提・実現したいこと

inputのような「範囲を超えた分を左右キーで表示」を、divに実装したいです。

たとえば次のコードならば、範囲を超えた「さしすせそ」あたりも左右キーで表示させることができますよね?

<input type="text" value="あいうえおかきくけこさしすせそ">

このような機能をdivに対しても実装したいと考えております。

尚、divの中身はtextareaの入力値をコピーしたものになります。

発生している問題

下記のソースコードですが、表示用のdivの文字が長いとき、見えなくなってしまうのが問題です。

先のinputでいえば「さしすせそ」あたりが見えなくなってしまうということです。

これを解決し、inputのような「範囲を超えた分を左右キーで表示」をdivにも実装したいわけです。

該当のソースコード

html

1 <div class="box"> 2 <textarea class="dammy"></textarea> 3 <div class="copy"></div> 4 </div>

css

1 .box { 2 position: relative; 3 width: 200px; 4 height: 40px; 5 margin: 0; 6 } 7 .dammy, 8 .copy { 9 border: none; 10 padding: 0.75rem 1rem; 11 width: 100%; 12 height: 40px; 13 line-height: 1.5; 14 min-height: 40px; 15 font-size: 1.5rem; 16 font-family: sans-serif; 17 white-space: nowrap; 18 overflow: hidden; 19 } 20 .dammy { 21 position: absolute; 22 z-index: 1; 23 caret-color: blue; 24 border: none; 25 background: transparent; 26 color: transparent; 27 resize: none; 28 } 29 .copy { 30 height: auto; 31 position: relative; 32 z-index: 0; 33 background: #ddd; 34 } 35 .copy .within { 36 color: blue; 37 white-space: nowrap; 38 display: inline; 39 } 40 .copy .overed { 41 color: red; 42 white-space: nowrap; 43 display: inline; 44 }

jquery

1 // 入力 2 $( document ).on( 'input', '.dammy', function( e ){ 3 const $dammy = $( this ); 4 // 改行禁止 5 enter( $dammy, e ); 6 // コピー 7 const lim = 5; 8 copy( $dammy, lim ); 9 }); 10 11 // 改行禁止 12 function enter( $dammy, e ){ 13 $dammy.on( 'keydown', function( e ) { 14 if ( e.which == 13 ) { return false; } 15 }); 16 const val = $dammy.val(); 17 const reg = new RegExp( "[\r\n]", "g" ); 18 if ( val.match(reg) ) { 19 const replace = val.replace( reg, '' ); 20 $dammy.val( replace ); 21 } 22 } 23 24 // コピー 25 function copy( $dammy, lim ){ 26 const $copy = $dammy.next( '.copy' ); 27 const val = $dammy.val(); 28 if ( val.length > lim ) { 29 const within = val.substr( 0, lim ); 30 const overed = val.slice( lim ); 31 $copy.html('<div class="within">' +within+ '</div>'); 32 $copy.append('<div class="overed">' +overed+ '</div>'); 33 } 34 else{ 35 $copy.html('<div><div class="within">' +val+ '</div></div>'); 36 } 37 }

試したこと

上は「textareaの入力値をdivにコピーする」という方法ですが、他にも「contenteditableをtrueにする」という方法を試しました。これならば「範囲を超えた分を左右キーで表示」が可能です。

ですが、お詳しい方ならご存じかと思いますが、HTMLを加えるとキャレット位置がズレてしまい修正が困難であったり、その他いろいろな点で問題がございましたので見送りました。

補足情報(FW/ツールのバージョンなど)

補足情報は特に現状ではありませんが、質問内容に不足などございましたら仰ってください。
質問は以上になります。ご協力いただけましたら幸甚に存じます。
何卒よろしくお願い致します。

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

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

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

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

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

siruku6

2019/10/06 07:00

サンプルコードが動作しませんでした。 <style>の閉じタグがないことは確認できたのですが、他にもありそうです。(入力してもdivに文字がコピーされるという動作が再現できないため) 実際に動作しているソースを貼り付けておきましょう。
kanimiso

2019/10/06 07:12

おっと、失礼いたしました。style閉じ忘れました。ありがとうございます。 あとは平気だと思います↓ https://jsfiddle.net/t7sjLh6a/
siruku6

2019/10/06 07:23

これで大丈夫そうですね。
guest

回答2

0

ベストアンサー

目的としては、textareaの中身が左右にスクロールした分だけ、divも左右にスクロール出来ればいい話なので。。。

とりあえずそれっぽくしてみました。

CSSは、
divのスクロール時の見た目を、テキストエリアと合わせるために、ちょっと調整します。。

css

1 .box { 2 position: relative; 3 width: 200px; 4 height: 40px; 5 margin: 0; 6 padding: 0.75rem 1rem; 7 line-height: 1.5; 8 background: #ddd; 9 } 10 .dammy, 11 .copy { 12 border: none; 13 padding: 0; 14 height: 40px; 15 line-height: 1.5; 16 min-height: 40px; 17 font-size: 1.5rem; 18 font-family: sans-serif; 19 white-space: nowrap; 20 overflow: hidden; 21 } 22 .dammy { 23 width: calc(100% - 2rem); 24 position: absolute; 25 z-index: 1; 26 caret-color: blue; 27 border: none; 28 background: transparent; 29 color: transparent; 30 resize: none; 31 } 32 .copy { 33 width: 100%; 34 height: auto; 35 position: relative; 36 z-index: 0; 37 background: #ddd; 38 } 39 .copy .within { 40 color: blue; 41 white-space: nowrap; 42 display: inline; 43 } 44 .copy .overed { 45 color: red; 46 white-space: nowrap; 47 display: inline; 48 }

js は、以下を追加

$(document).on('keyup', '.dammy', function(){ $(this).next('.copy').scrollLeft($(this).scrollLeft()); });

見ての通りkeyupしないとイベントが発火しないため、
左右キー長押しによって、カーソルが1文字ずつ移動するような動作に【追従するスクロール】は再現出来ません。(長押しは、キーを離すと位置が追いつきます)

もし、左右キー長押しも再現したいなら、keydownも使って「押し続けている間」にもdivのスクロール位置の調整処理を繰り返せるように。。と、もう少し工夫が必要になりますね。

※ windowsのChrome、Firefox、IE11、Edgeで簡単に動作確認はしましたが、ちょっとしか動かしてみてないので、もし不具合等ございましたらご容赦を。。

ご参考までに。。^^


コメント欄で話に出た「選択の動作」について追記します。

現状の入力欄は、textareaで、overflow:hiddenに設定されているため、
そもそもこの入力欄自体が、話にでたような「選択の動作」を行ってくれません。
なので、これを実現するためには、textarea自体に工夫が必要になります。

試しに、
マウスをクリックしてから離すまでの間、textareaの左右のスクロールを自動で調整するようにしてみました。

javascript

1 var scroller = false, dammy = false, mouse = false; 2 3 $( document ).on('mousedown', '.dammy', function(){ 4 //.dammyの上でマウスクリックが始まった場合に、自動スクロールの処理を繰り返し動作させます 5 dammy = this; 6 scroller = setInterval(dammy_scroll, 20); 7 }).on('mousemove', function(){ 8 //画面内で移動したマウスのポジションを使いたいのでここで保持しておきます。 9 mouse = event; 10 }).on('mouseup', function(){ 11 //どこかでマウスクリックが終わったら、繰り返し処理を削除します。 12 if(scroller){ 13 scroller = clearInterval(scroller); 14 } 15 dammy = false; 16 }); 17 18 function dammy_scroll(){ 19 if(!dammy){ 20 return ; 21 } 22 if($(dammy).offset().left > mouse.clientX){ //入力欄エリアよりも、マウスが左側にいる 23 $(dammy).scrollLeft($(dammy).scrollLeft() - 5); 24 }else if(($(dammy).offset().left + $(dammy).width()) < mouse.clientX){//入力欄エリアよりも、マウスが右側にいる 25 $(dammy).scrollLeft($('.dammy').scrollLeft() + 5); 26 } 27 //divのスクロール量を、textareaに合わせます。 28 $(dammy).next('.copy').scrollLeft($(dammy).scrollLeft()); 29 } 30

自動のスクロールを5pxにしたので、通常の「選択の動作」よりも若干ゆっくりですが、
大体似たような感じになった気がします。

ちなみに。

textareaの、overflow:hiddenを削除する(これだと、幅を超える文字数を入力した時に、スクロールバーが見えてしまいますので、そちらを隠す方法を検討する必要がありますね・・)
textareaではなくinputに変更する

のどちらかが可能なのであれば、
textarea/input自体が、話に出た「選択の動作」をしてくれるので、上記のようなコードは不要となり、

javascript

1var dammy= false; 2//画面外でマウスクリックが終わった時も反応したいので、イベント設定対象はdocumentに。 3$(document).on('mousedown', '.dammy',function(){ 4 dammy= this; 5}).on('mouseup', function(){ 6 if(dammy) 7 $(dammy).next('.copy').scrollLeft($(dammy).scrollLeft()); 8 } 9 dammy = false; 10});

とするだけでも、再現は出来そうでしたよ。

※追記のコードは、windowsのChromeで軽く動作確認しただけのものなので、その点はご了承を。

投稿2019/10/07 09:30

編集2019/10/08 08:37
mix-peach

総合スコア1910

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

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

kanimiso

2019/10/07 10:51

ありがとうございます。仰る通りkeydownに変えるだけでよりinputに近づきますが、そうされなかったのはなぜでしょうか?何か問題ございましたか? ところでこれは質問になく今気づいたことですが、そういえばinputとの違いとして選択の動作もできませんね。しかしJSで「カーソルでの選択エリアがボックス範囲を超えたとき」などというアクションは取得できるのでしょうか…?
mix-peach

2019/10/08 01:26 編集

私が動作確認していた限りだと、 keydownで処理を行うと、左右矢印キーを連打した時などに、テキストエリアのスクロール量より、divのスクロール量が1文字分くらい少なくなることがあったので、keyupのイベントを使いました。 「選択の動作」とは、どの動作のことでしょう? 入力欄に、「あいうえおかきくけこさしすせそ」と入力し、前半部分が見えない状態で、後ろの文字から左クリック長押して文字列を先頭に向かって範囲選択した時に、選択した先頭文字列の位置まで表示される部分がスクロールする動作、のことでしょうか?
kanimiso

2019/10/08 02:26

>スクロール量が1文字分くらい少なくなることがあった それは気づきませんでした。しかしなぜでしょうか。keydoenにしてもその幅が変わる原因は特に思い当たらないですよね。 >「選択の動作」とは 仰る通りです。そのようなアクションを拾うメソッドもまた思い当たらないですね…。
mix-peach

2019/10/08 05:30

スクロール量の差分は、イベント発生のタイミングが変わるせいかな?と思いました。 左右矢印キーを押した場合、input/textareaは、 ・1文字前か後にカーソルを移動させる。 ・カーソル位置が隠れていたら表示位置をスクロールする。 の、2つの処理を行っていると思われます。 で、ここに、div側のスクロール量調整の処理を追加しているイメージになります。 input/textareaの2つの処理と、追加した処理の処理順序は、恐らくブラウザ任せになるので、連打することによって、input/textarea側の処理より先に、div側のスクロール量調整の処理が動いてしまうのかも?(あくまで「かも」です^^; 選択の動作については、回答に追記しますね。
kanimiso

2019/10/08 05:40

すごいですね。input/textareaの挙動などろくに学んだことがなく、そのような予想は立ちませんでした。 選択の動作に光明が見えそうでしょうか!?それこそ当方には雲をつかむような話で、jQeury-UIを入れたりと迷走しているところですので笑、もしご追記頂けるのであれば大変ありがたく存じます。どうぞお手すきの折に宜しくお願い申し上げます。
kanimiso

2019/10/08 09:29

「選択の動作」に関する回答のご追記、誠にありがとうございます。scrollLeftというメソッドがあったんですね。そちらfirefoxでも動作しまして、inputに変更するプランが理想に近いとなりました。どうもありがとうございます。僭越ながらベストアンサーとさせて頂きました。 選択された青い範囲だけ微妙に文字の高さにずれが生じますが、その辺りはご愛敬(?)ということで勘弁してもらおうと思います。笑 たびたび誠に恐れ入りますが、最後にもう一つだけ教えて頂けないでしょうか。 ご追記のコードで、➀dammyにfalseを入れて、➁マウスの対象を入れて、➂ifで判定し、➃最後にfalseに戻していらっしゃいますよね?この一連の流れの意味がわかりませんでした。 もしお時間と余力がございましたら軽くご解説願えませんでしょうか。
mix-peach

2019/10/10 06:44

変数dammyは、mousedownのイベント設定がクラス指定のため、同名クラスの要素が複数ある前提で、スクロールの調整が必要な対象1つだけを保持して置くものです。 提示したコード上では、「dammy」に何か入っている間だけしか、dammy_scroll() が繰り返し呼ばれることはない、ようになっています。 が、今回、dammy_scroll()は、globalな関数で定義しているので、この関数自体が、上記コード外からも呼び出しが可能です。 想定外のところからdammy_scroll()が実行された場合、変数dammyの中身がないとエラーが発生しますし、変数dammyに「前回イベントの発生した.dammy」を入れっぱなしにしておくと、本来意図しないタイミングで、スクロール調整が動くことになってしまいます。(機能上、入れっぱなしの方は大した問題ではありませんが・・) この2点を回避するために、mouseup時にわざわざfalseを入れ直したり、dammy_scroll の中で、変数の存在判定を入れたりしました。 サンプルとしてお出ししたコードなので、このあたりの考慮は不要だったかもしれませんね。 ただ、簡単に想定できる問題になりうる点は回避できるように、ついこんな流れにしてしまいました。
kanimiso

2019/10/10 06:48

いえサンプルとしてお出し頂いたにも関わらず、すばらしいご考慮であったと感激しております。必要な機能でした。そのテクニックも当方では思いつくことはできなかったでしょうし、改めて感謝申し上げます。
guest

0

css と javascript の部分を以下のように変えれば、それなりに見える動きになりました。
ただし、青色、赤色に文字色を変えるという部分を削除してしまいましたので、そこは修正してみてください。

css

1 .box { 2 position: relative; 3 width: 200px; 4 height: 40px; 5 margin: 0; 6 } 7 .dammy, 8 .copy { 9 border: none; 10 padding: 0.75rem 1rem; 11 width: 100%; 12 height: 40px; 13 line-height: 1.5; 14 min-height: 40px; 15 font-size: 1.5rem; 16 font-family: sans-serif; 17 white-space: nowrap; 18 overflow: hidden; 19 } 20 .dammy { 21 position: absolute; 22 z-index: 1; 23 caret-color: blue; 24 border: none; 25 background: transparent; 26 color: transparent; 27 resize: none; 28 } 29 .copy { 30 height: auto; 31 position: relative; 32 z-index: 0; 33 background: #ddd; 34 } 35 .copy .within { 36 color: blue; 37 white-space: nowrap; 38 display: inline; 39 } 40 .copy .overed { 41 color: red; 42 white-space: nowrap; 43 display: inline; 44 } 45 46 /* style-sheet 追加 */ 47 .right-aligned { 48 position: sticky; 49 right: 0; 50 }

javascript

1 // 入力 2 $( document ).on( 'input', '.dammy', function( e ){ 3 const $dammy = $( this ); 4 // 改行禁止 5 enter( $dammy, e ); 6 // コピー 7 const lim = 5; 8 copy( $dammy, lim ); 9 }); 10 11 function enter( $dammy, e ){ 12 $dammy.on( 'keydown', function( e ) { 13 // 改行禁止 14 if ( e.which == 13 ) { 15 return false; 16 // 横矢印キー押下時の動作 17 } else if ( e.which == 39 ) { 18 $('.within').addClass('right-aligned'); 19 } else if ( e.which == 37 ) { 20 $('.within').removeClass('right-aligned'); 21 } 22 }); 23 const val = $dammy.val(); 24 const reg = new RegExp( "[\r\n]", "g" ); 25 if ( val.match(reg) ) { 26 const replace = val.replace( reg, '' ); 27 $dammy.val( replace ); 28 } 29 } 30 31 // コピー 32 function copy( $dammy, lim ){ 33 const $copy = $dammy.next( '.copy' ); 34 const val = $dammy.val(); 35 // if ( val.length > lim ) { 36 const within = val //.substr( 0, lim ); 37 // const overed = val.slice( lim ); 38 $copy.html('<div class="within">' +within+ '</div>'); 39 // $copy.append('<div class="overed">' +overed+ '</div>'); 40 // } else { 41 // $copy.html('<div><div class="within">' +val+ '</div></div>'); 42 // } 43 } 44

追記

次のような一つのhtmlファイルの状態にして、ファイルをダブルクリックしたところ、動作しました

残念なところとしては、隠れた部分を表示したとき、カーソルの位置と文字の位置が合っていないところです。
あくまで、できたのは「表示するだけ」になってしまっております....

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4 <head> 5 <title>Team1 Website</title> 6 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 7 8 <style> 9 .box { 10 position: relative; 11 width: 200px; 12 height: 40px; 13 margin: 0; 14 } 15 .dammy, 16 .copy { 17 border: none; 18 padding: 0.75rem 1rem; 19 width: 100%; 20 height: 40px; 21 line-height: 1.5; 22 min-height: 40px; 23 font-size: 1.5rem; 24 font-family: sans-serif; 25 white-space: nowrap; 26 overflow: hidden; 27 } 28 .dammy { 29 position: absolute; 30 z-index: 1; 31 caret-color: blue; 32 border: none; 33 background: transparent; 34 color: transparent; 35 resize: none; 36 } 37 .copy { 38 height: auto; 39 position: relative; 40 z-index: 0; 41 background: #ddd; 42 } 43 .copy .within { 44 color: blue; 45 white-space: nowrap; 46 display: inline; 47 } 48 .copy .overed { 49 color: red; 50 white-space: nowrap; 51 display: inline; 52 } 53 54 /* style-sheet 追加 */ 55 .right-aligned { 56 position: sticky; 57 right: 0; 58 } 59 </style> 60 61 <script> 62 // 入力 63 $( document ).on( 'input', '.dammy', function( e ){ 64 const $dammy = $( this ); 65 // 改行禁止 66 enter( $dammy, e ); 67 // コピー 68 const lim = 5; 69 copy( $dammy, lim ); 70 }); 71 72 function enter( $dammy, e ){ 73 $dammy.on( 'keydown', function( e ) { 74 // 改行禁止 75 if ( e.which == 13 ) { 76 return false; 77 // 横矢印キー押下時の動作 78 } else if ( e.which == 39 ) { 79 $('.within').addClass('right-aligned'); 80 } else if ( e.which == 37 ) { 81 $('.within').removeClass('right-aligned'); 82 } 83 }); 84 const val = $dammy.val(); 85 const reg = new RegExp( "[\r\n]", "g" ); 86 if ( val.match(reg) ) { 87 const replace = val.replace( reg, '' ); 88 $dammy.val( replace ); 89 } 90 } 91 92 // コピー 93 function copy( $dammy, lim ){ 94 const $copy = $dammy.next( '.copy' ); 95 const val = $dammy.val(); 96 // if ( val.length > lim ) { 97 const within = val //.substr( 0, lim ); 98 // const overed = val.slice( lim ); 99 $copy.html('<div class="within">' +within+ '</div>'); 100 // $copy.append('<div class="overed">' +overed+ '</div>'); 101 // } else { 102 // $copy.html('<div><div class="within">' +val+ '</div></div>'); 103 // } 104 } 105 </script> 106 </head> 107 108 <body> 109 <div class="box"> 110 <textarea class="dammy"></textarea> 111 <div class="copy"></div> 112 </div> 113 </body> 114 115</html>

投稿2019/10/06 07:44

編集2019/10/06 09:47
siruku6

総合スコア1382

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

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

kanimiso

2019/10/06 08:09

せっかくですが、どのような意図でお書きになり、何が解決したのか掴めませんでした。また別の機会がありましたら宜しくお願い致します。
siruku6

2019/10/06 09:37

表示用のdivで、「範囲を超えた分を左右キーで表示」ができるようにはなっていますが、それだけでは要件を満たしていないようですね。 他に満たさなければいけない条件があれば、質問内に記載しておいてもらえると助かります。
kanimiso

2019/10/06 09:41

いえ、それができれば問題ないです。どのような環境でできましたか?こちらで一通り実行しましたができなかったので、何が解決したのか掴めないと申し上げた次第です。
siruku6

2019/10/06 09:50 編集

1つのhtmlにすべてまとめ、windows上でそのファイルをダブルクリックしたところ、動作させることができました。 回答欄に追記しています。 残念ながら、使いにくい動作をしている部分があります...
kanimiso

2019/10/07 10:44 編集

やはり動作していないと思われます。こちら画像をご覧ください。 https://imgur.com/a/hTbKuhJ 「あいうえおかきくけ」までしか表示できず、左右キーで「こさしすせそ」などが表示されることはありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問