JavaScriptで要素編集時にテキストを隠す
それでは、編集時にその段落のテキストの代わりに、入力欄が段落内に表示されるようにしてみましょう。編集終了後には入力欄が消え、再び段落のテキストが表示されるようにします。
実装に取り掛かりましょう。
まず、段落をクリックすると、その段落の末尾にそのテキストが入った入力欄が追加されるようにします。
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.appendChild(input);
});
しかし、このコードは非常に不完全です。段落をクリックするたびに新しい入力欄が追加されてしまいます。
その場合、最初の入力欄には段落のテキストが入りますが、2番目の入力欄には段落のテキストに加えて最初の入力欄も含まれた内容が入り、3番目の入力欄には段落のテキストと2つの入力欄が含まれた内容が入る、というふうになってしまいます。
また、追加された入力欄をクリックすると、それは段落のクリックとして扱われる点にも注意してください。入力欄は段落の中にあるため、入力欄へのクリックは単にこの段落へとバブリング(伝播)するからです。
これにより、最初の入力欄が表示された後、編集を始めようとしてそれをクリックしようとすると、自動的に段落がクリックされたことになり、それに伴うすべての結果が生じてしまいます。
さて、問題が明確になりました。では、これを修正しましょう。
そのためには、入力欄が表示された時点で、段落からクリックハンドラを解除すればよいです。こうすれば、段落への最初のクリックだけが入力欄の表示を引き起こし、入力欄表示後に発生するそれ以降のクリックは無視されます。
実装しましょう。
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.appendChild(input);
elem.removeEventListener('click', func); // イベントを解除
});
では、入力欄が表示された時に、段落自体のテキストが消えるようにしましょう。そのためには、入力欄を挿入する前に、段落のtextContentに空文字列を代入します。
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent; // まず段落のテキストを入力欄に書き込む
elem.textContent = ''; // その後、段落のテキストを消す
elem.appendChild(input); // その後、入力欄を挿入する
elem.removeEventListener('click', func);
});
では、入力欄でフォーカスが外れた時(blur)に、その入力欄のテキストが段落に書き込まれるようにしましょう。
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.textContent = '';
elem.appendChild(input);
input.addEventListener('blur', function() {
elem.textContent = this.value;
});
elem.removeEventListener('click', func);
});
入力欄を削除する必要がないことに注意してください。入力欄は、自分のテキストを段落に書き込む時に自ら削除されます。入力欄は段落のテキストの一部であるため、何らかのテキストをこの段落に書き込むと、単に私たちの入力欄が削除されるからです。
しかし、まだ別の問題があります。段落のテキストは最初の1回だけ編集されることになります。1回目の編集後、段落のテキストを再度クリックしても何も起こりません。
その理由は、入力欄が表示された時点で、上述の理由により段落からイベントを解除してしまったからです。今度は、編集が終了した時点で、再度イベントを設定し直す必要があります。
それでは、そうしましょう。
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.textContent = '';
elem.appendChild(input);
input.addEventListener('blur', function() {
elem.textContent = this.value;
elem.addEventListener('click', func); // イベントを再度設定
});
elem.removeEventListener('click', func);
});
私のコードを見ないで、自分自身で説明された問題を解決してください。