Удалите пробелы и разрывы строк между элементами 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]*<

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

Ответ 1

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

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

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

$('#widget').cleanWhitespace();

Ответ 2

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

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;
}

Ответ 3

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

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);
 }
}

Ответ 4

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

Ответ 5

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

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

Сначала locato родительский node содержащий неприятные пробелы

$('.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>​, 
" ", 
"    "]

Perfect! у нас точно такая же структура, но внутри внутри объекта jQuery, поэтому давайте позвоним каждому и напечатаем "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, и теперь у нас есть undefined. Но это еще лучше, потому что там, где пространство может быть правдивым undefined, безусловно, falsy =)

Так что давайте избавимся от присосок с помощью 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>​]

И Валлах! Все сексуально и симпатично =)

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

NJoy!

Ответ 6

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

 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] );
      }
    }
  }

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

Ответ 7

Использование

$($.parseHTML(widgetHTML, document, true)).filter("*"),

Ответ 8

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