Удаление пробелов и разрывов строк между элементами HTML с помощью jQuery - PullRequest
39 голосов
/ 08 октября 2009

Используя 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]*<

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

Ответы [ 8 ]

60 голосов
/ 06 апреля 2010

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

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

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

$('#widget').cleanWhitespace();
32 голосов
/ 23 июня 2010

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

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;
}
20 голосов
/ 08 октября 2009

Думаю, так и будет ...

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);
 }
}
2 голосов
/ 18 сентября 2012

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

Вывод с хромированной консоли

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

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

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

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

Итак, чтобы добраться до элемента HTMLE, мы берем первый элемент в массиве с индексом 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-объекта nnow, поэтому давайте вызовем каждый из них и выведем «this» на консоль, чтобы посмотреть, что у нас есть.

$($('.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, и теперь у нас есть неопределенное значение. Но это даже лучше, потому что место, где пробел может быть правдиво неопределенным, определенно ложно =)

Итак, давайте избавимся от лохов с помощью 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.

NJoy!

2 голосов
/ 08 октября 2009

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

1 голос
/ 14 ноября 2012

Мне пришлось немного изменить принятый ответ, потому что по какой-то причине chrome не захотел удалить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] );
      }
    }
  }

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

0 голосов
/ 28 октября 2014

Используйте

$($.parseHTML(widgetHTML, document, true)).filter("*"),
0 голосов
/ 08 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...