Удалить пробелы и разрывы строк между элементами 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]*<
Можно ли это сделать без использования регулярных выражений?
8 ответов
Я попробовал технику, которую выложил 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();
Рекурсивная версия:
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;
}
Я думаю, что это сделает это...
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);
}
}
Вот что сработало для меня и пошагового открытия:
Выход из хромированной консоли
Сначала найдите родительский узел, содержащий неприятные пробелы
$('.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-объекта нет ничего, поэтому давайте вызовем каждый из них и выведем "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!
Вы можете сделать это лучше после установки HTML в DOM-узел. После того как браузер проанализировал все и построил дерево DOM из нашей разметки, вы можете выполнить обход DOM и для каждого найденного текстового узла либо полностью удалить его, если в нем нет непробельных символов, либо обрезать пробелы с самого начала и конец, если это так.
Мне пришлось немного изменить принятый ответ, потому что по какой-то причине 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] );
}
}
}
Он берет узел, из которого вы хотите удалить пробелы, и рекурсивно заменяет все дочерние пробелы действительно пустым текстовым узлом.
Использование
$($.parseHTML(widgetHTML, document, true)).filter("*"),
Вы могли бы $.trim(widgetHTML);
чтобы прочитать окружающие пробелы.