Ukrywanie tekstu podczas edycji elementu w JavaScript
Teraz sprawmy, aby podczas edycji input pojawiał się bezpośrednio w akapicie - zamiast tekstu tego akapitu. Niech potem po zakończeniu edycji input zostanie usunięty, a zamiast niego znów pojawi się tekst akapitu.
Przystąpmy do realizacji.
Na początek zróbmy tak, aby po kliknięciu w akapit na jego końcu dodawany był input z tekstem tego akapitu:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.appendChild(input);
});
Nasz kod jest jednak bardzo niedoskonały - za każdym razem po kliknięciu w akapit będzie do niego dodawany nowy input.
Przy tym, jeśli w pierwszym inpucie będzie znajdować się tekst akapitu, to w drugim inpucie będzie już znajdować się tekst akapitu razem z pierwszym inputem, a w trzecim inpucie będzie już znajdować się tekst akapitu razem z dwoma inputami i tak dalej.
Zwróć także uwagę na to, że kliknięcie dodanego inputu będzie interpretowane jako kliknięcie w akapit: chodzi o to, że input znajduje się w akapicie, i kliknięcie w input po prostu wypłynie (bubble) w górę do tego akapitu.
Doprowadzi to do tego, że po pojawieniu się pierwszego inputu przy próbie kliknięcia w niego po to, aby rozpocząć edycję, automatycznie zrobimy kliknięcie w akapit ze wszystkimi wynikającymi z tego konsekwencjami.
A zatem, problem został zarysowany. Teraz go naprawmy.
Aby to zrobić, po prostu przy pojawieniu się inputu odepnijmy od akapitu nasłuchiwacz zdarzenia kliknięcia. W tym przypadku tylko pierwsze kliknięcie w akapit będzie prowadzić do pojawienia się inputu, a pozostałe kliknięcia, wykonane po pojawieniu się inputu, zostaną zignorowane.
Zrealizujmy to:
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); // odpinamy zdarzenie
});
Zróbmy teraz tak, aby przy pojawieniu się
inputu, tekst samego akapitu znikał. W tym celu
przed wstawieniem inputu textContent akapitu
przypiszmy pustemu stringowi:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent; // najpierw zapisujemy tekst akapitu w inpucie
elem.textContent = ''; // następnie usuwamy tekst akapitu
elem.appendChild(input); // następnie wstawiamy input
elem.removeEventListener('click', func);
});
Zróbmy teraz tak, aby przy utracie fokusu w inpucie tekst tego inputu został zapisany w akapicie:
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);
});
Zwróć uwagę na to, że nie musimy usuwać inputu - usuwa się on sam, kiedy zapisuje swój tekst w akapicie: ponieważ input jest częścią tekstu akapitu, to zapis jakiegoś tekstu w ten akapit po prostu usuwa nasz input, i tyle.
Mamy jednak jeszcze jeden problem: tekst akapitu będzie edytowany tylko za pierwszym razem. Po pierwszej edycji ponowne naciśnięcie na tekst akapitu do niczego nie doprowadzi.
Chodzi o to, że w momencie pojawienia się inputu odpięliśmy zdarzenie od akapitu z opisanych powyżej przyczyn. Teraz musimy w momencie zakończenia edycji podpiąć zdarzenie z powrotem.
Zróbmy to:
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); // podpinamy zdarzenie z powrotem
});
elem.removeEventListener('click', func);
});
Samodzielnie, nie podglądając mojego kodu, rozwiąż opisane zadanie.