Возьмите, например, этот html:
<tag>sometext<tag>sometext</tag>sometext</tag>
Мне нужна функция javascript, которая может заменить это на:
<tag>sometext</tag><tag>sometext</tag><tag>sometext</tag>
Как мне это сделать ?
Я пытался сделать это с помощью регулярных выражений, но это не заменяет каждый вложенный тег, и я не знаю, есть ли выражение, которое может достичь этого.
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script>
function Unnest() {
document.getElementById("Nested").innerHTML = document.getElementById("Nested").innerHTML.replace(/<tag>(.*?)<tag>(.*?)</tag>(.*?)</tag>/g, '<tag>$1</tag><tag>$2</tag><tag>$3</tag>');
}
</script>
</head>
<body>
<div id = "Nested">
<tag>sometext<tag>sometext</tag>sometext</tag>
</div>
<button onclick = "Unnest()">Unnest</button>
</body>
</html>
@Peterrabbit Нет, здесь нет неработающих тегов. Исходная строка HTML действительна (исключая использование несуществующего тега).
Тогда, возможно, это может быть ответом на вашу проблему stackoverflow.com/questions/49967843/…
Это всего лишь пример возможного пути в зависимости от сложности ваших реальных тегов HTML, и, как таковой, проблема может быть чрезмерным упрощением. Например, если в вашей модели DOM много таких деревьев тегов с разным количеством дочерних узлов, вам нужно будет выбрать самый внешний тег каждого выбора; и если они вложены друг в друга, вам придется найти способ выбрать их или выполнить итерацию по их дочерним узлам, возможно, рекурсивно. Трудно сказать без дополнительной информации.
Тем не менее, если вы достаточно хорошо знаете структуру DOM, на которую вы ориентируетесь, вы можете попробовать такой подход и адаптировать его под себя.
Однако, если вы пытаетесь справиться с более общим сценарием или должны работать с HTML как со строкой, а не с использованием DOM, то, вероятно, потребуется другой подход, который анализирует строку.
let el = document.querySelector('tag').firstChild,
html = new Array();
while (el) {
switch (el.nodeName) {
case "TAG" :
html.push("<tag>" + el.textContent + "</tag>");
break;
case "#text" :
html.push("<tag>" + el.nodeValue + "</tag>");
break;
default :
console.info("Unexpected input");
}
el = el.nextSibling;
}
console.info( html.join(''));
<tag>sometext1<tag>sometext2</tag>sometext3</tag>
let tag = document.querySelector('tag'),
el = tag.firstChild,
frag = document.createDocumentFragment();
while (el) {
switch (el.nodeName) {
case "TAG" : {
let t = document.createElement('TAG');
t.classList.add('indiv');
t.textContent = el.textContent;
frag.appendChild(t);
break;
}
case "#text" : {
let t = document.createElement('TAG');
t.classList.add('indiv');
t.textContent = el.nodeValue;
frag.appendChild(t);
break;
}
default :
console.info("Unexpected input");
}
el = el.nextSibling;
}
tag.parentNode.replaceChild(frag,tag);
tag.indiv {
margin: 0 10px;
}
<tag>sometext1<tag>sometext2</tag>sometext3</tag>
@Massy Я должен был добавить, что строка была записана в консоль только для иллюстрации. Вы можете использовать метод DOM для полной замены узла после использования этого подхода для построения нового дерева, такого как document.createElement('TAG'), и установки его textContent в каждом case из switch. Вы можете добавить их к фрагменту документа, а затем заменить существующий узел вновь созданным фрагментом. Дело в том, что вам не обязательно использовать innerHTML. Или вы можете попробовать insertAdjacentHTML или insertAdjacentElement.
@Massy В пример ответа добавлен дополнительный фрагмент кода, касающийся приведенного выше комментария.
Это отвечает на ваш вопрос? stackoverflow.com/questions/41915184/…