Как избежать дублирование кода?

Есть задача: Дан массив. Выведите его элементы в виде списка ul. Нужно чтобы по клику на любую li в ней появлялся input, с помощью которого ее можно будет редактировать. Также чтобы под списком был input, с помощью которого можно будет добавить новый элемент в конец списка ul. Сделайте так, чтобы новые li также можно было редактировать и в конце каждой li стояла ссылка 'удалить', с помощью которой можно будет удалить эту li из ul.

let parent = document.querySelector('#parent');
let input = document.getElementById('input');
let arr = ['a', 'r', 'r', 'a', 'y'];
let ul = document.createElement('ul');
parent.appendChild(ul);

for (let elem of arr) {
  let li = document.createElement('li');
  li.textContent = elem;
  ul.appendChild(li);

  let span = document.createElement('span');
  span.textContent = li.textContent;
  li.textContent = '';
  li.appendChild(span);

  let a = document.createElement('a');
  a.href = '';
  a.textContent = ' ' + 'remove';
  li.appendChild(a);
  a.addEventListener('click', function(event) {
    li.remove();
    event.preventDefault();
  });
}


ul.addEventListener('click', function func() {
  if (event.target.tagName === 'SPAN') {
    let span = event.target;
    let inp = document.createElement('input');
    inp.value = span.textContent;
    span.textContent = '';
    span.appendChild(inp);

    inp.addEventListener('blur', function() {
      span.textContent = this.value;
      ul.addEventListener('click', func);
    });
    ul.removeEventListener('click', func);
  }
});


input.addEventListener('blur', function() {
  let li = document.createElement('li');
  li.textContent = this.value;
  ul.append(li);

  let span = document.createElement('span');
  span.textContent = li.textContent;
  li.textContent = '';
  li.appendChild(span);

  let a = document.createElement('a');
  a.href = '';
  a.textContent = ' ' + 'remove';
  li.appendChild(a);
  a.addEventListener('click', function(event) {
    li.remove();
    event.preventDefault();
  });
});
<div id="parent"></div>
<input id="input">

Хочется избежать повторение в двух местах при создании элемента span и а. Для решения проблемы дублирования пробовал одинаковый код вынести в функцию наружу, сделав ее Function Declaration. Но функция не работает как надо при добавление новых li с помощью input внизу списка. Как это сделать правильно?

let parent = document.querySelector('#parent');
let input = document.getElementById('input');
let arr = ['a', 'r', 'r', 'a', 'y'];
let li;
let ul = document.createElement('ul');
parent.appendChild(ul);

for (let elem of arr) {
  li = document.createElement('li');
  li.textContent = elem;
  ul.appendChild(li);

  addSpanAndLink();
}


ul.addEventListener('click', function func() {
  if (event.target.tagName === 'SPAN') {
    let span = event.target;
    let inp = document.createElement('input');
    inp.value = span.textContent;
    span.textContent = '';
    span.appendChild(inp);

    inp.addEventListener('blur', function() {
      span.textContent = this.value;
      ul.addEventListener('click', func);
    });
    ul.removeEventListener('click', func);
  }
});


input.addEventListener('blur', function() {
  let li = document.createElement('li');
  li.textContent = this.value;
  ul.appendChild(li);
  addSpanAndLink();
});



function addSpanAndLink() {
  let span = document.createElement('span');
  span.textContent = li.textContent;
  li.textContent = '';
  li.appendChild(span);

  let a = document.createElement('a');
  a.href = '';
  a.textContent = ' ' + 'remove';
  li.appendChild(a);
  a.addEventListener('click', function(event) {

    span.remove();
    event.preventDefault();
  });
}
<div id="parent"></div>
<input id="input">


Ответы (1 шт):

Автор решения: gord1402

Выносим создание span, a и li в отдельную функцию с аргументом text:

function AddNewPosition(text) {
  let li = document.createElement("li");
  li.textContent = text;
  ul.appendChild(li);

  let span = document.createElement("span");
  span.textContent = li.textContent;
  li.textContent = "";
  li.appendChild(span);

  let a = document.createElement("a");
  a.href = "";
  a.textContent = " " + "remove";
  li.appendChild(a);
  a.addEventListener("click", function(event) {
    li.remove();
    event.preventDefault();
  });
}

let parent = document.querySelector("#parent");
let input = document.getElementById("input");
let arr = ["a", "r", "r", "a", "y"];
let ul = document.createElement("ul");
parent.appendChild(ul);

for (let elem of arr) {
  AddNewPosition(elem);
}

ul.addEventListener("click", function func() {
  if (event.target.tagName === "SPAN") {
    let span = event.target;
    let inp = document.createElement("input");
    inp.value = span.textContent;
    span.textContent = "";
    span.appendChild(inp);

    inp.addEventListener("blur", function() {
      span.textContent = this.value;
      ul.addEventListener("click", func);
    });
    ul.removeEventListener("click", func);
  }
});

input.addEventListener("blur", function() {
  AddNewPosition(this.value);
});
<div id="parent"></div>
<input id="input" />

→ Ссылка