У меня есть инструмент, который используется для очистки дрянного HTML, чтобы разобраться в основной структуре. После удаления атрибутов class, style и различных атрибутов Angular часто результирующая разметка представляет собой серию вложенных элементов <div> или <span>, не имеющих атрибутов. Что я хотел бы сделать, так это предоставить возможность выполнить второй проход, когда <div> или <span> без атрибутов можно удалить, чтобы еще больше сгладить структуру.
Есть ли способ в JavaScript подтвердить, что элемент HTML не имеет каких-либо атрибутов?
И если это возможно, как я могу подойти к удалению элемента?
Например, если у меня есть это:
<div>
<div>
<div id = "blah">
<div>
<div>
<span dir = "auto">
<span>Joe Bloggs</span>
</span>
</div>
</div>
</div>
</div>
</div>
Это должно закончиться так:
<div id = "blah">
<span dir = "auto">
Joe Bloggs
</span>
</div>
Который я затем отформатировал бы:
<div id = "blah">
<span dir = "auto">
Joe Bloggs
</span>
</div>
Поэтому мне нужна функция, которая может обходить DOM и удалять div (или span), у которого нет атрибутов, при этом внутреннее содержимое остается нетронутым (если, конечно, любой из этих внутренних элементов также может быть удален по той же причине).
Будем признательны за любые указатели, прежде чем я займусь созданием дрянного (но работающего) скрипта!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


attributes недвижимость сообщит вам, сколько атрибутов имеет элемент.
const countAttributes = element => console.info({
count: element.attributes.length,
list: [...element.attributes].map(attribute => attribute.name)
});
const divs = document.querySelectorAll('div');
divs.forEach(countAttributes);<div></div>
<div class = "one attribute"></div>
<div class = "two attributes" id = "second attribute"></div>Обратите внимание, что элемент без атрибутов все еще может использоваться для чего-то (например, таблица стилей может ссылаться на него по отношению к другим элементам).
Спасибо, Квентин. Возможность удалять слои разметки предназначена только для упрощения структуры там, где это необходимо (случай, когда деревья не видны). Таким образом, мы можем игнорировать влияние CSS на то, как я это использую :)
Обновленный код
Ну вот.
document.querySelectorAll("div").forEach((ele) => {
if (ele.attributes.length === 0) {
var fragment = document.createDocumentFragment();
while (ele.firstChild) {
fragment.appendChild(ele.firstChild);
}
ele.parentNode.replaceChild(fragment, ele);
}
});<div>
<div>
<div id = "blah">
<div>
<div>
<span dir = "auto">
<span>Joe Bloggs</span>
</span>
</div>
</div>
</div>
</div>
</div><div id = "blah">
<span dir = "auto">
<span>Joe Bloggs</span>
</span>
</div>
Разве дети с атрибутами не будут удалены?
О да. Я обновил свой код. Спасибо что подметил это.
Спасибо, что предложили это. Единственное, что я заметил при таком подходе, - это то, что последний (самый глубокий) промежуток остается на месте. Хотя очень незначительная проблема :)
Последний диапазон остается на месте, потому что я только выбираю и удаляю элементы div. Чтобы выделить все элементы, вы можете заменить document.querySelectorAll("div") на document.querySelectorAll("*")
Он также удалит другие теги, такие как <body>, <head> и т. д.
Вот как я это сделал.
Я создал демонстрационный элемент, чтобы получить элементы, затем я проверил количество элементов, я проверил, нужно ли удалять элемент.
Я заменил элемент его дочерними элементами, а если их не было, я использовал его текст
function strip(startElement, toStrip) {
const test = document.createElement('div');
test.innerHTML = startElement.outerHTML;
[...test.querySelectorAll('*')].forEach(elem => {
if (!elem.attributes.length && toStrip.includes(elem.tagName.toLowerCase())) {
if (elem.children.length) elem.replaceWith(...elem.children);
else elem.replaceWith(elem.innerText);
} ;
});
return test.innerHTML;
}
console.info(strip(document.querySelector('div'), ['span', 'div']));<div>
<div>
<div id = "blah">
<div>
<div>
<span dir = "auto">
<span>Joe Bloggs</span>
</span>
</div>
</div>
</div>
</div>
</div>Похоже, он делает именно то, что мне нужно. Огромное спасибо. :)
Отлично: D, Если вы не возражаете, не могли бы вы также принять и проголосовать за ответ.
@CBroe Я не думаю, что это лучшая идея для разобрать
outerHTMLс помощью регулярного выражения, особенно если вы уже проанализировали его (DOM).