下記は新しく作成した要素内の、文字の大きさを変化させるイベントです。
コードが長いので一部抜粋したものになります。
背景と流れ
画面上にノートの様な見た目をした要素があるとします。
その要素の中に下記のイベント処理をします。
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