@Shimpanze

Почему JS-функция, останавливает выполнение после первого абзаца?

Необходимо оставить только теги li.
Из остальных тегов оставить только текст.

Код:

let html = `
<ol>
<li><a href="#"><code>foo</code> текст ссылки</a>;</li>
<li><a href="#"><code>bar</code> ещё текст ссылки</a>;</li>
</ol>
<p>Текст параграфа <code>baz</code> и <code>biz</code> ещё текст.</p>
<p>И ещё текст параграфа.</p>
`;

html = `<body>${html}</body>`;

let parsed = new DOMParser().parseFromString( html, 'text/html' );

function testFn( node  ) {

    node.childNodes.forEach( function( e ) {

        testFn( e );

        if ( e.nodeType !== Node.ELEMENT_NODE ) return;

        if ( e.nodeName.toLowerCase() !== 'li' ) {

            e.replaceWith( ...e.childNodes );
        }
    });
}

testFn( parsed.body );

console.log( parsed.body.innerHTML );


На выходе получаю:

<li>foo текст ссылки;</li>
<li>bar ещё текст ссылки;</li>

<p>Текст параграфа <code>baz</code> и <code>biz</code> ещё текст.</p>
<p>И ещё текст параграфа.</p>


То есть, отрабатывается только элемент ol, а до параграфов дело не доходит.

В чём дело?
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
@slide13
frontend/web-developer
childNodes включает не только элементы, но и тексты, комментарии, переносы строк. После парсинга p элементы находятся внутри текстовых переносов строк /n, поэтому когда производится проверка if ( e.nodeType !== Node.ELEMENT_NODE ) return; они игнорируются. Так что если требуется перебрать только элементы всегда нужно использовать children, а не childNodes. В данном случае все переносы строк буду проигнорированы и элементы p преобразуются как нужно.

function testFn(node) {
  for (const child of node.children) {
    testFn(child);
    if ( child.nodeName !== 'LI' ) {
      child.replaceWith( ...child.childNodes );
    }
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы