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

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

新規登録して質問してみよう
ただいま回答率
85.48%
イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

Q&A

1回答

1468閲覧

addEventLisner 同じ名前の選択した要素のみををイベントを発生させたい

rei78087487

総合スコア12

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

0グッド

0クリップ

投稿2021/03/16 07:14

編集2021/03/17 01:50

下記は新しく作成した要素内の、文字の大きさを変化させるイベントです。
コードが長いので一部抜粋したものになります。

背景と流れ

画面上にノートの様な見た目をした要素があるとします。
その要素の中に下記のイベント処理をします。

1、ダブルクリックイベントで要素を作成(要素は複製して作成可能)
2、作成した要素に対して、右クリックイベントを行うとメニューが表示される(文字の大きさ、文字の色、背景色、画像、削除等)
3、メニュー内の文字の大きさに触れると文字の大きさメニューが表示される
4、文字の大きさメニューは左から、テキストボックス、↑、↓がありテキストボックスには文字の大きさを決める数字が入っており、
↑や↓をクリックする事でテキストボックスの数字が-+1ずつ増減する。

問題点:

要素を複数作成(ここでは3つとする)した状態で上記の4を行うと、
・テキストボックスの増減が -+3になる
・作成した要素に対して4のイベントが同時に行われる

作成した要素の名前(child)はすべて同じであり、それがまとめてaddEventListenerで
処理されているからこういう問題が起きたと思われる。

改善方法:

addEventListnerでなく、イベントを単体で処理するonClickイベントで処理を行う事にした。
もちろん改善はされたが新たな問題点が出た。

新たな問題点:

要素を個別で処理出来るようになったが、onclickイベントは一番最後に記述したコードしか処理されない。
つまり下記ソースコード↑部分と↓部分に同じonclickイベントがあるので、一番下にあるコードに上書きされて↓のイベントしか
行われない。

実現したいこと

・要素が複数あっても単体別で処理したい
・任意の要素を複数選択した場合に同時に処理が出来る様にしたい。
(例:要素0~4まで作成。要素1,3を選択してこの二つのみ同時にイベント処理を行いたい
エクセルで言うとctrlキーを押しながらセルを複数選択)

上記を作成する場合、単体の処理では不可能なのでonclickイベントは使用されないものと思います。
そうなるとAddEventListenerになると思いますが…
どなたかご教示お願いします。

JavaScript

1***************************************イベント処理******************************** 2 3// 要素の作成 4const doubleClick = (e) => { 5 obj.elm = document.createElement('textarea'); 6 obj.elm.classList.add('child'); 7 const combine = obj.elm; 8 9 combine.onchange = () => { 10 if(combine.value !== "") { 11 combine.style.backgroundColor = 'transparent'; 12 combine.style.border = 'none'; 13 combine.style.resize = 'none'; 14 } else { 15 combine.style.backgroundColor = 'white'; 16 combine.style.border = 'solid'; 17 combine.style.borderWidth = 'thin'; 18 } 19 } 20 elment.appendChild(obj.elm); 21 obj.setPos(e); 22 obj.elm = null; 23}; 24 25 26 27// 右クリックメニュー 28const contextMenu = (e) => { 29 const rightClick = document.querySelector('.menu'); 30 let t = e.target; 31 if(t.nodeName != 'TEXTAREA' || !t.classList.contains('child')) return; 32 rightClick.style.display = "block"; 33 34 if(t.getBoundingClientRect().top > 216) { 35 rightClick.style.left = t.getBoundingClientRect().left + 'px'; 36 rightClick.style.top =t.getBoundingClientRect().top - 216 + 'px'; 37 } else { 38 rightClick.style.left = t.getBoundingClientRect().left + 'px'; 39 rightClick.style.top =t.getBoundingClientRect().top + 30 + 'px'; 40 } 41}; 42 43 44// 文字の大きさメニュー 右クリック➡文字の大きさ➡文字の大きさメニュー表示 45const mouseMove2 = () => { 46 fontMenu.style.display = "block"; 47}; 48 49 50 51// 文字の大きさメニュー 矢印↑クリック 52const contextMenu2 = (e) => { 53 let t = event.target; 54 const test = t; 55 if(t.nodeName != 'TEXTAREA' || !t.classList.contains('child')) return; 56 57 fontUp.addEventListener('click', (e) => { 58 if(inputFont.value >= 64) { 59 alert('64以上の数値は入力できません') 60 return; 61 } 62 inputFont.value = Number(inputFont.value) + 1; 63 t.style.fontSize = Number(inputFont.value) + 'px'; 64 }); 65} 66 67 68// 文字の大きさメニュー矢印↓クリック 69 70const contextMenu3 = (e) => { 71 let t = event.target; 72 if(t.nodeName != 'TEXTAREA' || !t.classList.contains('child')) return; 73 74   fontDown.addEventListener('click', (e) => { 75 if(inputFont.value >= 64) { 76 alert('64以上の数値は入力できません') 77 return; 78 } 79 inputFont.value = Number(inputFont.value) - 1; 80 t.style.fontSize = Number(inputFont.value) + 'px'; 81 }); 82} 83 84 85 86//addEventListner→onclickに変更した場合 87// 文字の大きさメニュー 矢印↑クリック 88 element.oncontextmenu = (e) => { 89 let t = event.target; 90 if(t.nodeName != 'TEXTAREA' || !t.classList.contains('child')) return; 91 92   fontUp.onclick = (e) => { 93 if(inputFont.value >= 64) { 94 alert('64以上の数値は入力できません') 95 return; 96 } 97 inputFont.value = Number(inputFont.value) + 1; 98 t.style.fontSize = Number(inputFont.value) + 'px'; 99 } 100 } 101 102 103// 文字の大きさメニュー矢印↓クリック 104 element.oncontextmenu = (e) => { 105 let t = event.target; 106 if(t.nodeName != 'TEXTAREA' || !t.classList.contains('child')) return; 107 108   fontDown.onclick = (e) => { 109 if(inputFont.value >= 64) { 110 alert('64以上の数値は入力できません') 111 return; 112 } 113 inputFont.value = Number(inputFont.value) - 1; 114 t.style.fontSize = Number(inputFont.value) + 'px'; 115 } 116 } 117

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

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

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

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

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

m.ts10806

2021/03/16 09:48

マークダウンのcodeできてないので、下記の質問など参照に「どうなっていればOKか」を確認したうえで質問内容調整してください。 https://teratail.com/questions/238564
yambejp

2021/03/17 01:47

サイズはドット単位で設定しているようですが5段階くらいで抑えたほうがよいのでは?
guest

回答1

0

もうすこし分からない部分を絞り込んで質問した方がよいですね
躓いたのはコンテキストメニューとテキストエリアの紐付けですか?

投稿2021/03/17 02:49

yambejp

総合スコア114843

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

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

rei78087487

2021/03/18 01:24

回答ありがとうございます。 また、アドバイスありがとうございます。 下記は現在のコードです。 https://codepen.io/mio-rei/pen/KKNLVKb 多々修正すべき点はお許しください。 説明がわかりづらく申し訳ございません、紐づけではないです。 作成した要素(テキストエリア)を複数作成した場合、作成した要素すべてに文字の大きさイベントが同時に発生してしまうという事です。 作成した要素に対して個別に文字の大きさをイベントとして処理したいのに、作成した要素にイベントが同時に起きてしまうので、そこで躓いています。 yambejp様の作成して頂いたコードの様に個別にかつ、 それに付随して任意の要素を複数選択した場合に同時に処理が出来る様にしたいです(上記内容) もしこれが、紐づけに問題がある場合は申し訳ございません。 宜しくお願い致します。
yambejp

2021/03/18 01:35 編集

> もしこれが、紐づけに問題がある場合は申し訳ございません。 ごめんなさい、うまく回答が伝わっていないですね テキストエリアに紐付いた値をコンテキストメニュー参照・変更したい のですよね?それを「紐付け」と表現したのですが うまく伝わらずにすみません。 ちなみに私のcodepenのソースがまさにそうなっていると思いますが どこが想定と違うのかを指摘ください
rei78087487

2021/03/18 02:16

早速の回答ありがとうございます。 テキストエリアに対する値の紐づけですね。 理解しました。 失礼致しました。 いえ、正に実現したい内容です。 ありがとうございます。 しかし、複数選択をして、選択した要素に対して同時にイベント処理するというのはJavascriptではできないのでしょうか?
yambejp

2021/03/18 02:23

複数選択のインターフェースをどうしたいかによりますね HTML自体にテキストエリアの複数選択UIはないと思いますが なにか方針はありますか? たとえばテキストエリアの前にチェックボックスをつけるとか・・・
rei78087487

2021/03/22 05:33 編集

現時点では方針という程ではありませんが、 yambejp様のヒントを元に考えた構想があります。 1.チェックボックスをを含めた要素を作成する(ダブルクリック) <div <input type=checkbox class=ip-class> <textarea class=child> </div> 2.作成した要素のどれかを右クリックしてメニューを表示 3.メニューに新たな項目(要素の選択)を追加する <li class="elm">要素の選択</li> 4.(要素を選択)の項目をクリックすると隠れていたチェックボックスが表示される const ipAll = document.querySelectorAll('.ip-class'); for (canvas of ipAll) { canvas.style.display = 'initial'; } }); 5.イベントを発生させたい要素のチェックボックスにチェックを付ける 6.チェックのついた要素が、文字の大きさメニューのイベントをまとめて発生させることができる この構想を元にコードを試作してみました。 ※ここでは試用段階としてチェックボックスをtrueにしたら要素が非表示になる設定。 ですが、うまく行っているのは最後に作成した要素のみで、他の要素のチェックボックスをtrueにしても非表示になりません。 何卒ご教示頂きたくお願いします。 yambejp様のコードを元に作成しました、失礼します。 https://codepen.io/mio-rei/pen/mdRbPQj
yambejp

2021/03/22 07:17

複数選択して調整する場合はcontextMenuは直感的ではないかもしれません。 専用の修正メニューを予め表示しておくなどの工夫が必要だと思います
rei78087487

2021/03/23 02:53

回答ありがとうございます。 少し考えてみます。 この構想を元にコードを試作してました~ の件ですが、なぜ最後の要素しか非表示のイベントが起きないのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問