Удалите пробелы и разрывы строк между элементами HTML с помощью jQuery.

Используя jQuery, я хотел бы удалить пробелы и разрывы строк между тегами HTML.

var widgetHTML = '    <div id="widget">        <h2>Widget</h2><p>Hi.</p>        </div>';

Должно быть:

alert(widgetHTML); // <div id="widget"><h2>Widget</h2><p>Hi.</p></div>

Я думаю, что шаблон мне понадобится:

>[\s]*<

Можно ли это сделать без использования регулярного выражения?


person mager    schedule 08.10.2009    source источник
comment
Почему следует избегать использования регулярных выражений? Это достаточно простая проблема, которую можно решить с помощью регулярных выражений, и все остальное, кажется, увеличивает сложность.   -  person Cam Soper    schedule 08.10.2009
comment
@CamSoper см.: stackoverflow.com/a/1732454/59087   -  person Dave Jarvis    schedule 12.02.2015


Ответы (8)


Я попробовал метод, который выложил пользователь 76888, и он работал хорошо. Я упаковал его в плагин jQuery для удобства и подумал, что сообществу он может понравиться, поэтому вот:

jQuery.fn.cleanWhitespace = function() {
    this.contents().filter(
        function() { return (this.nodeType == 3 && !/\S/.test(this.nodeValue)); })
        .remove();
    return this;
}

Чтобы использовать это, просто включите его в тег script, затем выберите тег для очистки с помощью jQuery и вызовите функцию следующим образом:

$('#widget').cleanWhitespace();
person The Digital Gabeg    schedule 06.04.2010
comment
Могу ли я предложить добавить return this; после очистки? Это позволит пользователю отключить вашу функцию. - person Matt Mills; 03.03.2011
comment
Отличная идея! Это то, что делает любая другая функция jQuery, моя функция тоже должна это делать. Сделанный. - person The Digital Gabeg; 03.03.2011
comment
Как раз то, что мне нужно, чтобы удалить пробелы между кнопками в JSP перед настройкой их полей. - person kevin cline; 29.07.2011
comment
Что я должен сделать здесь, чтобы удалить только те пустые узлы, которые появляются перед первым непустым узлом? Другие пустые узлы, которые находятся между ними, должны сохраняться как есть. Спасибо за любую помощь... - person teenup; 21.09.2011
comment
очень хорошо! Я бы назвал его removeWhitespace, а не cleanWhitespace. - person isapir; 08.09.2017

Рекурсивная версия:

jQuery.fn.htmlClean = function() {
    this.contents().filter(function() {
        if (this.nodeType != 3) {
            $(this).htmlClean();
            return false;
        }
        else {
            this.textContent = $.trim(this.textContent);
            return !/\S/.test(this.nodeValue);
        }
    }).remove();
    return this;
}
person Blago    schedule 23.06.2010
comment
Это сработало лучше, чем @user76888 и @the-digital-gabeg. Я просто немного изменил его на return this;, как и @the-digital-gabeg. Это решило мои проблемы с пробелами в таблицах, что является ошибкой IE9. - person John Yeary; 08.01.2013
comment
Это удаляет пробел после закрывающего сильного тега в следующей строке: ‹strong›текст‹/strong› больше текста. - person Marcus; 25.01.2015

Я думаю, это сделает это...

cleanWhitespace: function(element) {
 element = $(element);
 for (var i = 0; i < element.childNodes.length; i++) {
   var node = element.childNodes[i];
   if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
     Element.remove(node);
 }
}
person user76888    schedule 08.10.2009
comment
Этот метод хорош, но он не работает для IE (не 9), так как игнорирует текстовые узлы и подсчитывает только фактические узлы. Таким образом, вы не можете просмотреть их и удалить :( Но мне еще предстоит найти лучший способ... - person Tokimon; 23.12.2010

Вероятно, вы сможете сделать это лучше, установив HTML в узел DOM. После того, как браузер проанализировал все и построил DOM-дерево из нашей разметки, вы можете выполнить обход DOM и для каждого текстового узла, который вы найдете, либо полностью удалить его, если он не содержит символов, отличных от пробелов, либо обрезать пробелы в начале. и конец этому, если это так.

person levik    schedule 08.10.2009
comment
+1. $('<div>').append(widgetHTML) это начало. Оттуда вы проходите дочерние узлы внутри внешнего div. В конце вызовите .html(), и вы получите widgetHTML без пустых пробельных узлов. - person Roatin Marth; 08.10.2009

Это то, что сработало для меня и пошаговое открытие:

Вывод из консоли chrome

Сначала найдите родительский узел, содержащий неприятные пробелы.

$('.controls label[class="radio"]').parent();

[<div class=​"controls">​
<label class=​"radio">​…​</label>​
" "
"    "
<label class=​"radio">​…​</label>​
" "
"    "
</div>​]

Вы можете видеть, что это завернуто в массив из скобок [] jQuery всегда будет возвращать структуру, подобную массиву, даже если был найден один элемент.

Итак, чтобы добраться до HTMLElement, мы берем первый элемент массива с индексом 0.

$('.controls label[class="radio"]').parent()[0];

<div class=​"controls">​
<label class=​"radio">​…​</label>​
" "
"    "
<label class=​"radio">​…​</label>​
" "
"    "
</div>​

Обратите внимание, что скобок [] больше нет. Причина, по которой нам нужно это сделать, заключается в том, что jQuery будет игнорировать пробелы в dom, а HTMLElement — нет. Посмотрите, что происходит, когда мы обращаемся к свойству childNodes.

$('.controls label[class="radio"]').parent()[0].childNodes;

[<label class=​"radio">​…​</label>​, 
" ", 
"    ", 
<label class=​"radio">​…​</label>​, 
" ", 
"    "]

У нас снова есть массив, да, вы замечаете скобки [], но видите ли вы другое отличие, посмотрите на все запятые, которых мы не смогли получить с помощью jQuery. Спасибо, HTMLElement, но теперь мы можем вернуться к jQuery, потому что я хочу использовать каждый вместо цикла for, вы согласны со мной? Итак, давайте обернем массив в jQuery и посмотрим, что произойдет:

$($('.controls label[class="radio"]').parent()[0].childNodes);

[<label class=​"radio">​…​</label>​, 
" ", 
"    ", 
<label class=​"radio">​…​</label>​, 
" ", 
"    "]

Идеально! у нас есть точно такая же структура, но теперь внутри объекта jQuery, поэтому давайте вызовем каждый и выведем «это» на консоль, чтобы увидеть, что у нас есть.

$($('.controls label[class="radio"]').parent()[0].childNodes).each(function () { 
   console.log('|'+$(this).html()+'|');
});

|<input id="gender_f" name="gender" type="radio" value="f">Female|
|undefined|
|undefined|
|<input id="gender_m" name="gender" type="radio" value="m" checked="">Male|
|undefined|
|undefined|

Итак, мы используем jQuery для получения HTML-кода каждого элемента, стандартный материал `$(this).html, и, поскольку мы не видим пробелов, давайте заполним его вертикальной чертой |, хороший план, но что у нас здесь есть? Как видите, jQuery не умеет превращать пробелы в html, и теперь у нас есть undefined. Но это даже лучше, потому что там, где пробел может быть истинным undefined, он определенно ложный =)

Итак, давайте избавимся от лохов с помощью jQuery. Все, что нам нужно, это $(this).html() || $(this).remove(); давайте посмотрим:

$($('.controls label[class="radio"]').parent()[0].childNodes).each(function () { 
   $(this).html() || $(this).remove();
});

[<label class=​"radio">​…​</label>​, 
" ", 
"    ", 
<label class=​"radio">​…​</label>​, 
" ", 
"    "]

О, дорогая.. но не бойся! Каждый по-прежнему возвращает предыдущую структуру, а не ту, которую мы изменили, давайте посмотрим, что теперь возвращает наш первоначальный запрос.

$('.controls label[class="radio"]').parent();

[<div class=​"controls">​
<label class=​"radio">​…​</label>​
<label class=​"radio">​…​</label>​
</div>​]

И Валла! Все сексуально и красиво =)

Итак, у вас есть, как удалить пробелы между элементами/тегами в стиле jQuery.

нРадость!

person nickl-    schedule 18.09.2012

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

 var removeWhiteSpaceNodes = function ( parent ) {
    var nodes = parent.childNodes;
    for( var i =0, l = nodes.length; i < l; i++ ){
      if( nodes[i] && nodes[i].nodeType == 3 && !/\S/.test( nodes[i].nodeValue ) ){
        parent.replaceChild( document.createTextNode(''), nodes[i]  );
      }else if( nodes[i] ){
        removeWhiteSpaceNodes( nodes[i] );
      }
    }
  }

Он берет узел, из которого вы хотите удалить пробелы, и рекурсивно заменяет все дочерние пробелы действительно пустым текстовым узлом.

person Quickredfox    schedule 13.11.2012

Использовать

$($.parseHTML(widgetHTML, document, true)).filter("*"),
person Specc    schedule 28.10.2014

Вы можете $.trim(widgetHTML); прочитать окружающие пробелы.

person Jojo    schedule 08.10.2009
comment
вопрос не в том, чтобы обрезать пробелы вокруг html-кода. речь идет об удалении пробелов между тегами html. - person Arash Milani; 28.04.2012