我有一个这样的div设置:
<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>
编辑:澄清一下,这是最简单的例子。 div可以有任意数量的n个深嵌套子项。
$('#test').getText()
返回&#39; Hello Goodbye&#39;。这是在Firebug中测试的一个班轮:jQuery('<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>').text()
这似乎是因为jQuery在内部使用,textContent(对于非IE),将隐藏元素作为文本的一部分返回。 Hrmph。
有没有办法返回文本内容忽略display:none&#39; d元素?基本上我试图模仿你用鼠标突出显示div并复制到系统剪贴板的文本。这忽略了隐藏的文字。
有趣的是,如果您创建一个选择范围并从中获取文本,那么它也会返回display:none元素内的文本。
var range = document.body.createTextRange();
range.moveToElementText($('#test')[0]);
range.select();
console.log(range.toString()); // Also logs Hello Goodbye!
因此,创建文档选择范围似乎与使用鼠标在display:none元素方面突出显示相同。我如何解决这个肮脏的泡菜难题?
修改:建议使用.filter(':visible').text
,但它不适用于此方案。我需要返回的文本完全是用鼠标选择的结果。例如:
$('<div>test1 <p>test2</p>\r\n <b>test3</b> <span style="display:none">none</span></div>').appendTo(document.body).children().filter(':visible').text()
返回
"test2test3"
当我真正想要的输出是
时test1 test2
test3
来自\ r \ n
的换行符,空格和所有内容答案 0 :(得分:4)
使用.filter(":visible")
过滤元素。
或者使用它:
$("#test :visible").text();
但jQuery documentation建议我们改用.filter()
:
因为:visible
是jQuery扩展而不是CSS规范的一部分,
使用:visible
的查询无法利用本机DOM querySelectorAll()
方法提供的性能提升。要在使用时获得最佳性能:可见选择元素,首先使用纯CSS选择器选择元素,然后使用.filter(":visible")
。
答案 1 :(得分:2)
在选择器中使用:visible
:
$("#test > p:visible").text()
功能示例:
- 编辑:
http://jsfiddle.net/8H5ka/(适用于Chrome,在结果中显示“Hello”)
如果上述方法无效:
答案 2 :(得分:1)
如果空间不是主要问题,您可以复制标记,删除隐藏的元素,然后输出该文本。
var x = $('#test').clone();
x.filter(':not(:visible)').remove();
return x.text();
答案 3 :(得分:0)
我遇到了这个问题并发现了这个问题,看起来实际的解决方案是基于提供的答案而不是实际写出来的。所以这里有一个完整的解决方案,适用于我的情况,这与OP相同,附加规定元素可能由于基于DOM位置的外部样式而不可见。例如:
<style>.invisible-children span { display: none; }</style>
<div class="invisible-children">
<div id="test">Hello <span>Goodbye</span></div>
</div>
解决方案是:
#test
从DOM中取出,jQuery可能不知道它们是不可见的,因为它们将不再符合CSS规则。代码:
var $test = $('#test');
// 1:
var $testclone = $test.clone();
// 2: We assume that $test is :visible and only remove children that are not.
$test.find('*').not(':visible').remove();
// 3:
var text = $test.text();
// 4:
$test.replaceWith($testclone);
// Now return the text...
return text;
// ...or if you're going to keep going and using the $test variable, make sure
// to replace it so whatever you do with it affects the object now in DOM and
// not the original from which we got the text after removing stuff.
$test = $testclone;
$test.css('background', 'grey'); // For example.
答案 4 :(得分:0)
以下是我使用MooTools的方法:
$extend(Selectors.Pseudo, {
invisible: function() {
if(this.getStyle('visibility') == 'hidden' || this.getStyle('display') == 'none') {
return this;
}
}
});
Element.implement({
getTextLikeTheBrowserWould = function() {
var temp = this.clone();
temp.getElements(':invisible').destroy();
return temp.get('text').replace(/ |&/g, ' ');
}
})
答案 5 :(得分:0)
我进行搜索,发现了这个问题,但没有解决方案。 对我来说,解决方案是退出jquery以使用DOM:
var $test = $('#test').get(0).innerText
或者如果选择器数组中的元素多于on元素,则需要一个for循环和一个合并,但是我想大多数时候它是您需要的第一个版本。
var $test = $('#test').get().map(a => a.innerText).join(' ');