Ocultando texto ao editar um elemento em JavaScript
Agora vamos fazer com que, durante a edição, o campo de entrada apareça no próprio parágrafo - substituindo o texto desse parágrafo. E que, ao terminar a edição, o campo de entrada seja removido, e o texto do parágrafo volte a aparecer no lugar.
Vamos começar a implementação.
Para começar, vamos fazer com que, ao clicar no parágrafo, um campo de entrada com o texto desse parágrafo seja adicionado ao final dele:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function() {
let input = document.createElement('input');
input.value = elem.textContent;
elem.appendChild(input);
});
No entanto, nosso código é muito imperfeito - a cada clique no parágrafo, um novo campo de entrada será adicionado a ele.
Com isso, se o primeiro campo de entrada contiver o texto do parágrafo, o segundo campo de entrada já conterá o texto do parágrafo junto com o primeiro campo de entrada, e o terceiro campo de entrada conterá o texto do parágrafo junto com dois campos de entrada, e assim por diante.
Preste atenção também ao fato de que um clique no campo de entrada adicionado será interpretado como um clique no parágrafo: o problema é que o campo de entrada está localizado dentro do parágrafo, e o clique no campo de entrada simplesmente se propagará para cima, até este parágrafo.
Isso levará ao seguinte: após o aparecimento do primeiro campo de entrada, ao tentar clicar nele para começar a editar, nós automaticamente faremos um clique no parágrafo, com todas as consequências resultantes.
Pronto, o problema foi delineado. Agora vamos corrigi-lo.
Para isso, simplesmente, quando o campo de entrada aparecer, vamos desvincular o manipulador de clique do parágrafo. Nesse caso, apenas o primeiro clique no parágrafo levará ao aparecimento do campo de entrada, e os demais cliques, feitos após o aparecimento do campo de entrada, serão ignorados.
Vamos implementar:
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); // desvincula o evento
});
Agora vamos fazer com que, quando o campo de entrada aparecer,
o texto do próprio parágrafo desapareça. Para isso,
antes de inserir o campo de entrada, vamos atribuir uma string vazia
ao textContent do parágrafo:
let elem = document.querySelector('#elem');
elem.addEventListener('click', function func() {
let input = document.createElement('input');
input.value = elem.textContent; // primeiro escrevemos o texto do parágrafo no campo de entrada
elem.textContent = ''; // depois removemos o texto do parágrafo
elem.appendChild(input); // depois inserimos o campo de entrada
elem.removeEventListener('click', func);
});
Agora vamos fazer com que, quando o campo de entrada perder o foco, o texto desse campo de entrada seja escrito no parágrafo:
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);
});
Preste atenção ao fato de que não precisamos excluir o campo de entrada - ele se exclui sozinho quando escreve seu texto no parágrafo: como o campo de entrada faz parte do texto do parágrafo, a escrita de algum texto nesse parágrafo simplesmente exclui nosso campo de entrada, e pronto.
No entanto, temos mais um problema: o texto do parágrafo será editado apenas na primeira vez. Após a primeira edição, um novo clique no texto do parágrafo não levará a nada.
O problema é que, no momento em que o campo de entrada apareceu, nós desvinculamos o evento do parágrafo pelos motivos descritos acima. Agora precisamos, no momento do término da edição, vincular o evento novamente.
Vamos fazer isso:
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); // adiciona o evento novamente
});
elem.removeEventListener('click', func);
});
Resolva de forma independente, sem olhar o meu código, o problema descrito.