Идентифицировать элемент HTML, у которого нет * атрибутов какого-либо типа, с помощью JavaScript?

У меня есть инструмент, который используется для очистки дрянного 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), у которого нет атрибутов, при этом внутреннее содержимое остается нетронутым (если, конечно, любой из этих внутренних элементов также может быть удален по той же причине).

Будем признательны за любые указатели, прежде чем я займусь созданием дрянного (но работающего) скрипта!

@CBroe Я не думаю, что это лучшая идея для разобрать outerHTML с помощью регулярного выражения, особенно если вы уже проанализировали его (DOM).

FZs 30.03.2021 13:35
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
47
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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 на то, как я это использую :)

Ian Lloyd 31.03.2021 18:57

Обновленный код

Ну вот.

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>
So final output would be
<div id = "blah">
  <span dir = "auto">
    <span>Joe Bloggs</span>
  </span>
</div>

Разве дети с атрибутами не будут удалены?

a.mola 30.03.2021 13:53

О да. Я обновил свой код. Спасибо что подметил это.

TechySharnav 30.03.2021 14:01

Спасибо, что предложили это. Единственное, что я заметил при таком подходе, - это то, что последний (самый глубокий) промежуток остается на месте. Хотя очень незначительная проблема :)

Ian Lloyd 31.03.2021 18:59

Последний диапазон остается на месте, потому что я только выбираю и удаляю элементы div. Чтобы выделить все элементы, вы можете заменить document.querySelectorAll("div") на document.querySelectorAll("*")

TechySharnav 01.04.2021 08:14

Он также удалит другие теги, такие как <body>, <head> и т. д.

TechySharnav 01.04.2021 08:15
Ответ принят как подходящий

Вот как я это сделал.

Я создал демонстрационный элемент, чтобы получить элементы, затем я проверил количество элементов, я проверил, нужно ли удалять элемент.

Я заменил элемент его дочерними элементами, а если их не было, я использовал его текст

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>

Похоже, он делает именно то, что мне нужно. Огромное спасибо. :)

Ian Lloyd 31.03.2021 18:58

Отлично: D, Если вы не возражаете, не могли бы вы также принять и проголосовать за ответ.

a.mola 31.03.2021 19:10

Другие вопросы по теме