Чистый способ написания innerHTML с помощью простого Javascript

#javascript

Вопрос:

У меня есть куча элементов списка, которые должны иметь теги, классы и все такое. Я получаю данные JSON с сервера и создаю li элементы, используя appendChild на a ul .

Вот пример функции для построения элементов «леммы».

 function createLemmaItem(lemma) {
  // bunch of "lemma" attributes -- create the base li
  let total = lemma.forms.length;
  let node = document.createElement("li");
  node.classList.add("lemma-item");
  node.dataset.lemmaId = lemma.id;
  node.dataset.group = lemma.group;
  node.setAttribute("onclick", "activateLemma(this)");

  // set the innerHTML to a long HTML string
  node.innerHTML = `
  <div class="lemma-col-1">
    <label>
      <input type="checkbox" onclick="lemmaToggleAll(this)" checked>
      ${lemma.name}
    </label>
  </div>
  <div class="lemma-col-2">
  ${lemma.latin}
  </div>
  <div class="lemma-col-3">
  ${lemma.homid}
  </div>
  <div class="lemma-col-4">
  <span class="counter">(<span class="total">${total}</span>/<span class="max">${total}</span>)</span>
  </div>`;
  return node;
}
 

Другой пример для элемента «форма» :

 function createFormItem(lemma, form) {
  let node = document.createElement("li");
  node.classList.add("form-item");
  node.classList.add("hidden");
  node.dataset.lemmaId = lemma.id;
  node.dataset.group = lemma.group;
  node.innerHTML = `
  <label>
    <input type="checkbox" name="${lemma.name}@${lemma.latin}@${lemma.homid}@${lemma.group}@${form}" onchange="changeCount(this)"checked>
    ${form}
  </label>`
  return node;
}
 

Затем я создаю элементы, используя эту функцию, чтобы сгенерировать каждый из них, а затем добавить его в ul с appendChild помощью .

Мне это кажется довольно запутанным и становится еще более запутанным, когда у меня более длинные HTML-строки. Меня беспокоит читаемость, ремонтопригодность и хрупкость моего кода, когда я делаю это таким образом.

Как вы обычно обрабатываете длинные HTML-строки, подобные этой, которые находятся в середине файлов JS (без использования фреймворка)? Есть ли канонический способ? Поместите строки в отдельный файл или что-то в этом роде?

Комментарии:

1. «строки в другом файле» не будут работать с литералами шаблонов

2. @JaromandaX Да, я так и понял.

3. Я не уверен, что это легко с вашим кодом, но вы можете использовать элементы <шаблон><шаблон>

4. @JaromandaX Читает об этом сейчас… кажется, это может быть действительно полезно. правка: УДИВИТЕЛЬНО! Это может быть именно то, что мне нужно! Спасибо, ты Джей Си Джениус!

Ответ №1:

Как вы обычно обрабатываете длинные HTML-строки, подобные этой, которые находятся в середине файлов JS (без использования фреймворка)? Есть ли канонический способ? Поместите строки в отдельный файл или что-то в этом роде?

Размещение отчетливо различных частей сценария в отдельных файлах значительно упрощает поддержку. Гораздо приятнее иметь возможность, например, перемещаться lemmaHTML.js и изменять в нем то, что вам нужно, чем управлять-F через монолитный файл из 500 строк или 2500 строк .js , содержащий весь ваш сценарий.

Один из способов достичь этого-использовать модули ES6. Вы можете создать модуль, который экспортирует функцию, создающую строку HTML. Например, у вас может быть createLemmaItem.js файл:

 export function createLemmaItem(lemma) {
  // ...
}
// nothing else in this file
 

И сделайте то же самое для createFormItem.js .

Чтобы импортировать их, запустите сценарий модуля и просто выполните

 import { createLemmaItem } from './createLemmaItem.js';
 

и используйте createLemmaItem идентификатор по мере необходимости.

Другой аналогичный подход заключается в использовании пакета модулей, такого как Webpack, для записи всего в модулях ES6, как описано выше, но для объединения всех ваших отдельных файлов в один для производства. Это позволяет устаревшим браузерам, таким как IE, использовать ваш код и значительно улучшит проблемы с подключением к большим приложениям. (Если у вас сотни модулей, выполнение отдельного запроса для каждого модуля может занять слишком много времени для загрузки клиентами.)

Хотя, если ты в этот момент где ваш скрипт большой, а ты беспокоишься о ремонтопригодности, я очень рекомендую, глядя в рамках, как реагировать — я знаю, ты сказал, что не хочу, но что-то вроде того, что действительно проверенные и истинно профессиональный подход в наше время, в сравнении с ванильным JS и DOM манипуляции.

Комментарии:

1. Круто, это отличный ответ и, честно говоря, отличный подход. Я думаю, что попытаюсь объединить ваш подход с использованием тегов HTML <шаблон>. Я не уверен, откуда взялись отрицательные отзывы на этот вопрос, но SE предупредил меня, что подобные вопросы в прошлом были отклонены, возможно, это потому, что в настоящее время все используют React. Но я хочу изучить основы, прежде чем использовать фреймворк.

Ответ №2:

Намного чище и проще с <template> .

Создание форм:

 function createFormItem(lemma, form) {
  let template = document.querySelector("#form-item");
  let node = template.content.cloneNode(true);

  let name = document.createTextNode(form);
  node.querySelector("label").append(name);

  let li = node.querySelector("li");
  li.dataset.lemmaId = lemma.id;
  li.dataset.group = lemma.group;
  return node;
}
 

Создание лемм:

 function createLemmaItem(lemma) {
  let template = document.querySelector("#lemma-item");
  let node = template.content.cloneNode(true);

  let name = document.createTextNode(lemma.name);
  node.querySelector("label").append(name);

  let li = document.querySelector("li");
  li.dataset.lemmaId = lemma.id;
  li.dataset.group = lemma.group;

  let col2 = node.querySelector("div.lemma-col-2");
  let latin = document.createTextNode(lemma.latin);
  col2.append(latin);

  let col3 = node.querySelector("div.lemma-col-3");
  let homid = document.createTextNode(lemma.homid);
  col3.append(homid);

  let count = lemma.forms.length;
  let max = node.querySelector(".max");
  let total = node.querySelector(".total");
  max.innerHTML = count;
  total.innerHTML = count;

  return node;
}
 

И теперь их можно поместить в отдельный файл, чтобы сделать все еще проще.