Как лучше подгружать xml с перерисовкой таблицы?

Ссылка скопирована
1 ответ

Сейчас ситуация такая: подскажите, как сделать, чтобы таблицы заменялись, а не заполняли страницу, выстраиваясь друг под другом. То есть необходимо, чтобы при нажатии на ссылку появлялась другая таблица, а у меня они появляются друг за другом.

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> <style> table, th, td { border: 1px solid black; border-collapse: collapse; } th, td { padding: 5px; } </style> </head> <body> <nav><a href="users">Users</a> | <a href="users2">Users2</a> | <a href="users3">Users3</a></nav> <div id="content"></div> <script> const contentDiv = document.getElementById("content"); function loadContent(fileName){ const xhr = new XMLHttpRequest(); xhr.onload = () => { if (xhr.status == 200) { const xmlDoc = xhr.responseXML; const table = createTable(); // выбираем все элементы user const users = xmlDoc.getElementsByTagName("user"); for (let i = 0; i < users.length; i++) { const user = users[i]; const userName = user.getAttribute("name"); const userAge = user.getAttribute("age"); const contact = user.querySelector("contacts email").textContent; const row = createRow(userName, userAge, contact); table.appendChild(row); } contentDiv.appendChild(table); } }; xhr.open("GET", fileName + ".xml"); xhr.responseType = "document"; xhr.setRequestHeader("Accept", "text/xml"); xhr.send(); } // устанавливаем обработчик нажатия для кнопок const links = document.getElementsByTagName("a"); for (let i = 0; i < links.length; i++) { links[i].addEventListener("click", (e)=>{ loadContent(links[i].getAttribute("href")); e.preventDefault(); }); } // по умолчанию загружаем компонент home loadContent("users"); // создаем таблицу function createTable() { const table = document.createElement("table"); const headerRow = document.createElement("tr"); const nameColumnHeader = document.createElement("th"); const ageColumnHeader = document.createElement("th"); const contactColumnHeader = document.createElement("th"); nameColumnHeader.appendChild(document.createTextNode("Name")); ageColumnHeader.appendChild(document.createTextNode("Age")); contactColumnHeader.appendChild(document.createTextNode("Contacts")); headerRow.appendChild(nameColumnHeader); headerRow.appendChild(ageColumnHeader); headerRow.appendChild(contactColumnHeader); table.appendChild(headerRow); return table; } // создаем одну строку для таблицы function createRow(userName, userAge, userContact) { const row = document.createElement("tr"); const nameColumn = document.createElement("td"); const ageColumn = document.createElement("td"); const contactColumn = document.createElement("td"); nameColumn.appendChild(document.createTextNode(userName)); ageColumn.appendChild(document.createTextNode(userAge)); contactColumn.appendChild(document.createTextNode(userContact)); row.appendChild(nameColumn); row.appendChild(ageColumn); row.appendChild(contactColumn); return row; } </script> </body> </html>
import { createServer } from "http"; import { readFile } from "fs"; createServer((request, response)=>{ // получаем путь после слеша, слеш - первый символ в пути let filePath = request.url.substring(1); // если пустой путь, отправляем главную страницу index.html if(!filePath) filePath = "index.html"; // в качестве типа ответа устанавливаем html response.setHeader("Accept", "text/xml; charset=utf-8;"); readFile(filePath, (error, data)=>{ if(error){ // если ошибка response.statusCode = 404; response.end("<h1>Resourse not found!</h1>"); } else{ response.end(data); } }); }).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Анна SEO Ответ

Если при каждом клике новая таблица добавляется ниже предыдущей, значит вы используете добавление в DOM, например append, innerHTML += или создаёте новый контейнер, вместо замены содержимого старого контейнера. Нужно иметь один блок для таблицы и перед каждой отрисовкой очищать или заменять его содержимое.

HTML:

&lt;div id="tableContainer"&gt;&lt;/div&gt;

JS-логика:

async function loadTable(url) {
  const response = await fetch(url);
  const xmlText = await response.text();
  const xml = new DOMParser().parseFromString(xmlText, 'text/xml');
 
  const table = buildTableFromXml(xml);
  const container = document.getElementById('tableContainer');
  container.replaceChildren(table);
}

Если формируете строкой, используйте присваивание, а не +=:

container.innerHTML = htmlTable;

А не так:

container.innerHTML += htmlTable;

Если ссылки переключают таблицы, отменяйте стандартный переход и вызывайте загрузку:

document.querySelectorAll('[data-xml]').forEach(link =&gt; {
  link.addEventListener('click', event =&gt; {
    event.preventDefault();
    loadTable(link.dataset.xml);
  });
});

Также желательно показывать состояние загрузки и ошибку, чтобы пользователь понимал, что происходит:

container.textContent = 'Загрузка...';
try {
  await loadTable(url);
} catch (e) {
  container.textContent = 'Не удалось загрузить XML';
}

Если XML большой, не перерисовывайте всю страницу. Меняйте только область таблицы, а фильтры, заголовки и кнопки оставляйте снаружи контейнера. Так пользователь не потеряет фокус, а код будет проще поддерживать.

Ещё один момент: не храните старые обработчики на удалённых строках таблицы. Если внутри таблицы есть кнопки, навешивайте обработчик после каждой отрисовки или используйте делегирование событий на контейнере.

Итог: создайте один контейнер таблицы и каждый раз заменяйте его содержимое через replaceChildren или innerHTML = .... Не используйте добавление через append/+=, если нужна именно смена таблицы. Для стабильного интерфейса добавьте состояние загрузки, обработку ошибок и очищайте только область с результатом, а не весь документ.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно