Альтернатива jQuery text (), которая включает пробелы между элементами?
у меня есть произвольный текст в контейнере. Я не контролирую его, поэтому не знаю его структуры. Но что-то вроде этого:--3-->
<div id='content-area'>
<h1>Heading</h1>
<p>A paragraph or two</p>
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
</div>
Это просто простой пример для иллюстрации, на самом деле он может содержать гораздо больше элементов и вложенных вещей, таких как таблицы.
Я хочу вытащить весь текст и сделать некоторые обработки на используемых слов. Я использую следующий jQuery для получения текста.
$('#content-area').text()
// HeadingA paragraph or twoitem 1item 2
проблема в том, что нет пробелов между каждый помеченный элемент. The документация говорит:
из-за различий в синтаксических анализаторах HTML в разных браузерах возвращаемый текст может отличаться в новых строках и других пробелах.
и все мои поиски, похоже, подтягивают результаты для удаления пробела. Есть ли способ вытащить весь текст и сохранить пространство между элементами? Должно произойти в браузере, поэтому методы javascript-ish.
5 ответов
в случае неизвестной вложенной структуры вы можете добавить пробелы в каждый элемент
https://jsfiddle.net/3y2yLexv/1/
$( "*" ).each(function( index ) {
$( this ).append(' ');
});
var str = $('#content-area').text();
//Of course you have to trim duplicated blank spaces.
str = str.replace(/\s\s+/g, ' ');
$('#new').text(str);
Я думаю, что jQuery использует свойство textContent, которое может форматировать вашу строку таким образом. Вместо этого вы можете пройти по дереву, ища textNodes и добавить его в строку/массив.
например:
function getText(domElement) {
var root = domElement;
var text = [];
function traverseTree(root) {
Array.prototype.forEach.call(root.childNodes, function(child) {
if (child.nodeType === 3) {
var str = child.nodeValue.trim();
if (str.length > 0) {
text.push(str);
}
} else {
traverseTree(child);
}
});
}
traverseTree(root);
return text.join(' ');
}
var text = getText(document.getElementById('content-area'));
document.getElementById('results').innerHTML = text;
<div id='content-area'>
<h1>Heading</h1>
<p>A paragraph or two</p>
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
</div>
<pre id="results"></pre>
есть куча текстовых узлов с символами пробелов. То, что я сделал, чтобы отфильтровать их, - это обрезать содержимое текстового узла, а затем просто проверить, есть ли что-нибудь рядом с пробелами. Могли бы быть лучше проверить, какие пробелы появляются и просто отфильтровать их.
вы можете использовать jQuery each
метод для сбора элементов и включения интервалов с помощью конкатенации строк.
что-то в этом роде для грубого примера:
$(function(){
var output = "";
$( "li" ).each( function( index, element ){
output += $(this).text() + " ";
});
$('#output').html(output);
});
не стесняйтесь видеть вывод, отображаемый путем кэширования того, что вы хотите, в переменную, которая сделает это так, что это только запись в DOM один раз.
EDIT:
Если вы понятия не имеете, что такое структура есть, но вы уверены, что все они будут в пределах одного div, вы можете использовать универсальный селектор jQuery.
$(function(){
var output = "";
$( "#content-area *" ).each( function( index, element ){
output += $(this).text() + " ";
});
$('#output').html(output);
});
Я не уверен, что это работает в любом случае. Мое решение будет регулярным выражением, которое фильтрует теги, пробелы и новые строки из raw html:
$("#content-area").html().replace(/([\s\n]*<[^>]*>[\s\n]*)+/g," ")
http://jsfiddle.net/limond/mrnctqcv/1/
EDIT: конечно, это работает, только если вы можете избежать любых тегов, содержащих html, которые пользователь не может видеть (например,<script>...</script>
)
Я решил это, добавив пробел: pre в css. При добавлении элемента динамически с помощью jquery вы можете сделать это так:
$('<a/>')
.attr("style", 'white-space:pre;')
.text(' X ');