使用.text()仅检索不嵌套在子标记中的文本
如果我有这样的HTML:
<li id="listItem"> This is some text <span id="firstSpan">First span text</span> <span id="secondSpan">Second span text</span> </li>
我试图用.text()
来检索string“这是一些文本”,但如果我说$('#list-item').text()
,我得到“这是一些textFirst跨度textSecond span text“。
有没有办法通过像.text("")
的标签中的自由文本(而不是其子标签内的文本)来获取(也可能删除,通过.text("")
)?
HTML不是由我写的,所以这是我必须要处理的。 我知道在编写html文件时将文本包装在标签中会很简单,但是再次预先写好html。
我喜欢这个基于在这里find的clone()
方法的可重用实现,只获得父元素内的文本。
代码仅供参考:
$("#foo") .clone() //clone the element .children() //select all the children .remove() //remove all the children .end() //again go back to selected element .text();
简单的回答:
$("#listItem").contents().filter(function(){ return this.nodeType == 3; })[0].nodeValue = "The text you want to replace with"
这似乎是过度使用jquery的一个例子。 以下将抓取文本忽略其他节点:
document.getElementById("listItem").childNodes[0];
你将需要修剪,但它可以得到你想要的,在一个简单的线。
编辑
以上将获得文本节点 。 要获得实际的文本,使用这个:
document.getElementById("listItem").childNodes[0].nodeValue;
更简单快捷:
$("#listItem").contents().get(0).nodeValue
类似于接受的答案,但没有克隆:
$("#foo").contents().not($("#foo").children()).text();
这是一个jQuery插件为此目的:
$.fn.immediateText = function() { return this.contents().not(this.children()).text(); };
这里是如何使用这个插件:
$("#foo").immediateText(); // get the text without children
不是代码:
var text = $('#listItem').clone().children().remove().end().text();
只是成为jQuery的jQuery的缘故? 当简单的操作涉及到许多链接命令和那么多(不必要的)处理时,也许是时候写一个jQuery扩展:
(function ($) { function elementText(el, separator) { var textContents = []; for(var chld = el.firstChild; chld; chld = chld.nextSibling) { if (chld.nodeType == 3) { textContents.push(chld.nodeValue); } } return textContents.join(separator); } $.fn.textNotChild = function(elementSeparator, nodeSeparator) { if (arguments.length<2){nodeSeparator="";} if (arguments.length<1){elementSeparator="";} return $.map(this, function(el){ return elementText(el,nodeSeparator); }).join(elementSeparator); } } (jQuery));
致电:
var text = $('#listItem').textNotChild();
参数是在遇到不同的情况下,例如
<li>some text<a>more text</a>again more</li> <li>second text<a>more text</a>again more</li> var text = $("li").textNotChild(".....","<break>");
文字将有价值:
some text<break>again more.....second text<break>again more
它需要根据需求量身定制,这取决于你所呈现的结构。 对于你提供的例子,这个工作:
$(document).ready(function(){ var $tmp = $('#listItem').children().remove(); $('#listItem').text('').append($tmp); });
演示: http : //jquery.nodnod.net/cases/2385/run
但是它相当依赖于你所发布的标记。
尝试这个:
$('#listItem').not($('#listItem').children()).text()
$($('#listItem').contents()[0]).text()
Stuart答案的简短变体。
或者用get()
$($('#listItem').contents().get(0)).text()
这是一个古老的问题,但最重要的答案是非常低效的。 这是一个更好的解决scheme:
$.fn.myText = function() { var str = ''; this.contents().each(function() { if (this.nodeType == 3) { str += this.textContent || this.innerText || ''; } }); return str; };
只要做到这一点:
$("#foo").myText();
jQuery.fn.ownText = function () { return $(this).contents().filter(function () { return this.nodeType === Node.TEXT_NODE; }).text(); };
把它放在<p>
或<font>
并抓住$('#listItem font')。text()
首先想到的东西
<li id="listItem"> <font>This is some text</font> <span id="firstSpan">First span text</span> <span id="secondSpan">Second span text</span> </li>
我提出了一个特定的解决scheme,该解决scheme应该比克隆的克隆和修改更有效率。 这个解决scheme只适用于以下两个保留,但应该比目前接受的解决scheme更有效率:
- 你只得到文本
- 您要提取的文本位于子元素之前
这就是说,这里是代码:
// 'element' is a jQuery element function getText(element) { var text = element.text(); var childLength = element.children().text().length; return text.slice(0, text.length - childLength); }
我build议使用createTreeWalker来查找所有不附加到html元素的文本元素(这个函数可以用来扩展jQuery):
function textNodesOnlyUnder(el) { var resultSet = []; var n = null; var treeWalker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, function (node) { if (node.parentNode.id == el.id && node.textContent.trim().length != 0) { return NodeFilter.FILTER_ACCEPT; } return NodeFilter.FILTER_SKIP; }, false); while (n = treeWalker.nextNode()) { resultSet.push(n); } return resultSet; } window.onload = function() { var ele = document.getElementById('listItem'); var textNodesOnly = textNodesOnlyUnder(ele); var resultingText = textNodesOnly.map(function(val, index, arr) { return 'Text element N. ' + index + ' --> ' + val.textContent.trim(); }).join('\n'); document.getElementById('txtArea').value = resultingText; }
<li id="listItem"> This is some text <span id="firstSpan">First span text</span> <span id="secondSpan">Second span text</span> </li> <textarea id="txtArea" style="width: 400px;height: 200px;"></textarea>
我认为这也是一个很好的解决scheme – 如果你想获得所有文本节点的内容是所选元素的直接子节点。
$(selector).contents().filter(function(){ return this.nodeType == 3; }).text();
注意:jQuery文档使用类似的代码来解释内容函数: https : //api.jquery.com/contents/
PS还有一个更丑陋的方法来做到这一点,但这更深入地展示了事情的工作原理,并允许在文本节点之间自定义分隔符(也许你想在那里换行)
$(selector).contents().filter(function(){ return this.nodeType == 3; }).map(function() { return this.nodeValue; }).toArray().join("");
这对我来说是一个好方法
var text = $('#listItem').clone().children().remove().end().text();
你可以试试这个
alert(document.getElementById('listItem').firstChild.data)
为了能够修剪结果,使用DotNetWala就像这样:
$("#foo") .clone() //clone the element .children() //select all the children .remove() //remove all the children .end() //again go back to selected element .text() .trim();
我发现使用像document.getElementById("listItem").childNodes[0]
这样的短版本不适用于jQuery的trim()。
使用额外的条件来检查innerHTML和innerText是否相同。 只有在这些情况下,才能更换文字。
$(function() { $('body *').each(function () { console.log($(this).html()); console.log($(this).text()); if($(this).text() === "Search" && $(this).html()===$(this).text()) { $(this).html("Find"); } }) })
我不是一个jQuery的专家,但如何,
$('#listItem').children().first().text()