Рекурсивно удалить пустые узлы из HTML

0

Я хотел бы удалить пустые элементы из некоторой строки html. Я знаю, что могу запустить что-то вроде:

$('p').each(function(index, item) {
    if($.trim($(item).text()) === "") {
        $(item).remove();
    }
});

Проблема в том, что я хочу удалить все пустые узлы - не только p. Также я хочу, чтобы сценарий рассматривал p-узел в <p><span></span></p> как пустой, поскольку он содержит только пустые элементы. У вас есть простая реализация чего-то подобного?

[EDIT] Я забыл добавить: я могу использовать jQuery, но html, который я хочу просмотреть и редактировать, находится в строке, а не в самом документе. Итак, как я могу сделать эту операцию? Я попытался использовать var html = $.parseHTML('<p><span></span></p>') но после каждого цикла я все равно получаю одну и ту же строку...

  • 0
    Чтобы выбрать все элементы, $ ('*'), но будьте осторожны с этим, может быть безопаснее иметь список элементов, которые имеет смысл удалить, например, $ ('p, h1, h2') или что-то подобное, как вы может не захотеть удалять тег <br/> или <hr />. Что касается вложенных элементов, я не уверен.
  • 0
    Ссылаться на этот jsfiddle.net/LEKaL/6
Показать ещё 2 комментария
Теги:
string

5 ответов

3
Лучший ответ

Недавно я искал решение той же проблемы. Ответ был рекурсивной.

function removeEmptyTagsRecursively($el) {
    if ($el.children().length) {

        $el.children().each(function(i, val) {
            removeEmptyTagsRecursively($(val));
        });

        $el.children(':empty').remove();
    }
}

Скрипт здесь: https://jsfiddle.net/635utakr/9/

  • 0
    Отличный пример рекурсивной функции :)
0

Здесь tweek функции Пола для ванили JS (требует Element.matches() polyfill):

function removeEmpty(parent) {
    // for each child
    [].forEach.call(parent.children, function(child) {
        // repeat operation
        removeEmpty(child);

        // remove if it matches selector
        if (child.matches(':empty')) {
            parent.removeChild(child);
        }
    });
}
0

На самом деле ваш код работает нормально. Смотрите эту скрипку.

Это показывается только с содержанием внутри. Тогда что вы хотите?

HTML

<p>hi 1</p>
<p></p>
<p><span>hi 2</span></p>
<p><span></span></p>

скрипт

$('p').each(function(index, item) {
    if($.trim($(item).text()) === "") {
        $(item).remove();
    }
});
  • 0
    См. Мои правки ... На самом деле я не хочу работать с html-документом, но с какой-то пользовательской строкой - это означает, что $ (item) .remove () не совсем подходит.
  • 0
    лучше, дай еще немного кода
0

Вы можете достичь этого, используя код ниже:

function removeEmptyTag(root) {
    var $root = $(root);
    $root.contents().each(function () {
    if (this.nodeType === 1) {
        removeEmptyTag(this);
    }
    });

    if (!$root.is("area,base,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr") && !$root.html().trim().length) {
    $root.remove();
    }
}

removeEmptyTag("#divIdHere");

скрипка

0

Попробуйте что-нибудь вроде

do {
    empty = $("*:empty");
    count = empty.length;
    empty.remove();
}
while ( count > 0 );

Это итеративный, а не рекурсивный, но должен сделать трюк

Ещё вопросы

Сообщество Overcoder
Наверх
Меню