Skrijemo besedilo pri urejanju elementa v JavaScript

Naj naredimo tako, da se med urejanjem vnosno polje prikaže v samem odstavku - namesto besedila tega odstavka. Naj se nato ob koncu urejanja vnosno polje odstrani, namesto njega pa spet prikaže besedilo odstavka.

Loto začnimo z implementacijo.

Za začetek naredimo tako, da ob kliku na odstavek na njegov konec doda vnosno polje z besedilom tega odstavka:

javascriptlet elem = document.querySelector('#elem');

elem.addEventListener('click', function() {
  let input = document.createElement('input');
  input.value = elem.textContent;
  
  elem.appendChild(input);
});

Vendar je naša koda zelo nepopolna - ob vsakem kliku na odstavek se mu bo dodalo novo vnosno polje.

Pri tem, če bo v prvem vnosnem polju stal besedilo odstavka, potem bo v drugem vnosnem polju že stalo besedilo odstavka skupaj s prvim vnosnim poljem, v tretjem vnosnem polju pa bo že stalo besedilo odstavka skupaj z dvema vnosnima poljema in tako naprej.

Opozorimo tudi na to, da se klik na dodano vnosno polje šteje kot klik na odstavek: dejstvo je, da se vnosno polje nahaja v odstavku in klik na vnosno polje preprosto odpluje navzgor k temu odstavku.

To bo povzročilo, da se po pojavu prvega vnosnega polja ob poskusu, da nanj kliknemo zato, da začnemo z urejanjem, avtomatično izvede klik na odstavek z vsemi posledicami, ki iz tega izhajajo.

Torej, problem je opisan. Naj ga zdaj popravimo.

Za to preprosto ob pojavu vnosnega polja odvežimo od odstavka obravnavo klikov. V tem primeru bo samo prvi klik na odstavek povzročil pojav vnosnega polja, preostali kliki, narejeni po pojavu vnosnega polja, pa bodo prezrti.

Implementirajmo:

javascriptlet 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); // odvežemo dogodek
});

Naj zdaj naredimo tako, da ob pojavu vnosnega polja besedilo samega odstavka izgine. Za to pred vstavitvijo vnosnega polja textContent odstavka priredimo prazni niz:

javascriptlet elem = document.querySelector('#elem');

elem.addEventListener('click', function func() {
  let input = document.createElement('input');
  
  input.value = elem.textContent; // najprej zapišemo besedilo odstavka v vnosno polje
  elem.textContent = ''; // nato odstranimo besedilo odstavka
  elem.appendChild(input); // nato vstavimo vnosno polje
  
  elem.removeEventListener('click', func);
});

Naj zdaj naredimo tako, da se ob izgubi fokusa v vnosnem polju besedilo tega vnosnega polja zapiše v odstavek:

javascriptlet 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);
});

Opozorimo na to, da nam ni treba brisati vnosnega polja - ono se izbriše samo, ko zapiše svoje besedilo v odstavek: ker je vnosno polje del besedila odstavka, zapis kakšnega besedila v ta odstavek preprosto izbriše naše vnosno polje, in to je vse.

Imamo pa še eno težavo: besedilo odstavka se bo urejalo le prvič. Po prvem urejanju ponovni pritisk na besedilo odstavka ne bo pripeljal do ničesar.

Dejstvo je, da smo v trenutku pojavljanja vnosnega polja odvezali dogodek od odstavka po zgoraj opisanih razlogih. Zdaj moramo v trenutku konca urejanja dogodek ponovno pripeti.

Naredimo to:

javascriptlet 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); // ponovno postavimo dogodek
  });
  
  elem.removeEventListener('click', func);
});
Задание 1

Samostojno, brez zaganjanja v mojo kodo, rešite opisano nalogo.