Я ищу способ заключить, что весь текст в jQuery перенес набор, но я должен создать пространства между одноуровневыми узлами, которые не имеют никаких текстовых узлов между ними.
Например, рассмотрите этот HTML:
<div>
<ul>
<li>List item #1.</li><li>List item #2.</li><li>List item #3.</li>
</ul>
</div>
Если я просто использую jQuery text()
метод для сбора текстового содержания <div>
, как такой:
var $div = $('div'), text = $div.text().trim();
alert(text);
это производит следующий текст:
Элемент списка № 1. Элемент списка № 2. Элемент списка № 3.
потому что нет никакого пробела между каждым <li>
элемент. То, что я на самом деле ищу, является этим (отметьте одиночный пробел между каждым предложением):
Элемент списка № 1. Элемент списка № 3. Элемент списка № 3.
Это предлагает мне, чтобы я пересек узлы DOM в перенесенном наборе, добавив текст для каждого к строке, сопровождаемой пространством. Я попробовал следующий код:
var $div = $('div'), text = '';
$div.find('*').each(function() {
text += $(this).text().trim() + ' ';
});
alert(text);
но это произвело следующий текст:
Это - элемент списка № 1. Это - элемент списка № 2. Это - элемент списка № 3. Это - элемент списка № 1. Это - элемент списка № 2. Это - элемент списка № 3.
Я предполагаю, что это вызвано тем, что я выполняю итерации через каждого потомка <div>
и добавление текста, таким образом, я получаю текстовые узлы в обоих <ul>
и каждый из <li>
дети, ведя к дублированному тексту.
Я думаю, что мог, вероятно, находить/писать плоскость функцией JavaScript для рекурсивного обхода DOM перенесенного набора, собираясь и добавляя текстовые узлы - но являюсь там более простым способом сделать это использование jQuery? Непротиворечивость перекрестного браузера очень важна.
Спасибо за любую справку!
jQuery работает в основном с элементами, его возможности по работе с текстовыми узлами относительно слабы. Вы можете получить список всех дочерних элементов с помощью contents()
, но вам все равно придется пройтись по нему, проверяя типы, так что это ничем не отличается от использования обычного DOM childNodes
. Не существует метода рекурсивного получения текстовых узлов, поэтому вам придется написать что-то самостоятельно, например, что-то вроде:
function collectTextNodes(element, texts) {
for (var child= element.firstChild; child!==null; child= child.nextSibling) {
if (child.nodeType===3)
texts.push(child);
else if (child.nodeType===1)
collectTextNodes(child, texts);
}
}
function getTextWithSpaces(element) {
var texts= [];
collectTextNodes(element, texts);
for (var i= texts.length; i-->0;)
texts[i]= texts[i].data;
return texts.join(' ');
}
Вы можете использовать метод jQuery contents () , чтобы получить все узлы (включая текстовые узлы), а затем отфильтровать свой набор только до текстовых узлов.
$("body").find("*").contents().filter(function(){return this.nodeType!==1;});
Оттуда вы можете создать любую структуру, которая вам нужна.