我的网站转换Japanese Kanji into romaji (roman letters):
并且输出显示并隐藏了CSS
用户需要查看的内容,具体取决于他们的输入条件。例如:
<div id="output">
<span class="roman">watashi</span>
<span class="english">I</span>
</div>
界面允许用户在watashi
或I
之间切换和输出,具体取决于他们想要查看的内容。
CSS
使用jQuery
和切换按钮隐藏其中一个或另一个。 (隐藏机制包括简单地向body
添加一个类并让CSS
做它的事情。)
问题在于,当用户将文本复制/粘贴到Word
时,它会复制所有内容。所以我决定使用系统来复制使用JavaScript
和jQuery
粘贴文本,但问题会重演:
$('#output').text()
即使watashi I
在页面本身不可见,输出I
而不是watashi
。有没有办法得到可见的文字?
答案 0 :(得分:17)
其他解决方案没有给我我需要的东西。
我的回答是:
$('#output *:not(:has(*)):visible').text()
你不应该在某个根元素下询问所有元素的文本。
为什么呢? - 它将重复输出并忽略隐藏标志
让我们看一个简单的例子
<div id="output" class="my-root">
<div class="some-div">
<span class="first" style="display:none"> hidden text </span>
<span class="second" > visible text </span>
</div>
<div>
现在如果我做$('#output').children(":visible").text()
我会得到.some-div
和.second
..
事实上.some-div
对我来说毫无顾虑......
当我在这些元素上询问text()
时,.some-div
也会返回隐藏文字。
所以技术上marcgg的解决方案是错误的恕我直言......
现在,为了正确回答这个问题,我们必须做出一个假设。对我来说,这似乎是合理的。
假设是文本只出现在叶元素中..
所以我们不会看到这样的事情:
<div id="output" class="my-root">
<div class="some-div">
<span class="first" style="display:none"> hidden text </span>
<span class="second" > visible text </span>
</div>
some text here..
<div>
为什么这个假设对我来说似乎合情合理?有两个原因:
根据这个假设,你想要做的是请求所有叶元素(没有子元素的元素),过滤掉可见元素,并询问它们的文本..
$('#output *:not(:has(*)):visible').text()
这应该会产生正确的结果。
评论表明,有时你只需要在leaf元素之外有文本
<div> This is some <strong style="display:none"> text </strong> </div>
正如您所看到的,您将<strong>
作为一个叶子,并且在此示例中通常会在其外部显示文本。
你可以解决我上面建议的解决方法..但如果你不能怎么办?
您可以克隆dom,然后删除所有隐藏的元素。
这里的问题是,为了:visible
选择器或:hidden
选择器工作,我必须在文档上有dom元素(这意味着用户实际可见)。
因此,这种方法会带来一些副作用,所以要小心。
这是一个例子
这个html
<div id="output" class="my-root">
<span>
some text <strong style="display:none">here.. </strong>
</span>
</div>
这个javascript工作
$(function(){
var outputClone = $('#output').clone();
$('#output :hidden').remove();
console.log($('#output').text()); // only visible text
$('#output').replaceWith(outputClone);
console.log($('#output').text()); // show original state achieved.
})
请参阅plunker here
如上所述 - 副作用可能看起来像一个瞬间闪烁,或一些应该运行的初始化脚本..有些原始思维可能会避免(div大小为1px / 1px以包含克隆和原始内容?)取决于你的情景。
答案 1 :(得分:11)
答案 2 :(得分:3)
在现代浏览器中尝试此操作(此处&#39; element&#39;是非JQuery DOM对象):
function getVisibleText(element) {
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(element);
window.getSelection().addRange(range);
var visibleText = window.getSelection().toString().trim();
window.getSelection().removeAllRanges();
return visibleText;
}
然后:
getVisibleText(document.getElementById('output'));
答案 3 :(得分:1)
盖伊有正确的答案。
但是,我正在处理一个“this”对象,所以为了得到他的工作答案,你需要使用以下语法......
$('*:not(:has(*)):visible', this).text()
答案 4 :(得分:1)
var lookup = function(element, text) {
//DFS Recursive way of finding text on each level
//Visible only works on elements that take up space(i.e. not fixed position elements)
var results = element.children(':visible');
//Look at the text at each level with the children removed
var newText = '';
results.each(function(index, value) {
newText += $(value).clone()
.children()
.remove()
.end()
.text();
});
var moreResultText = '';
results.each(function(index, value) {
moreResultText += lookup($(value), text);
})
if (results.length > 0) {
return text + newText + moreResultText;
} else {
return text;
}
};
lookup($('#output'), ''));
大多数其他功能在页面的大部分区域运行时会崩溃,这应该是一种更准确的方法来确定实际显示给用户的内容,而不会破坏页面,也不会返回不可见的文本用户。
当然要小心,这不会保留任何格式化感,并且元素之间输出的间距可能不正确。此外,它可能无法正确排序返回的文本,在这些方面,它的用法将受到限制。另一个考虑因素是可见的真正定义对于nail down来说有点困难,但是对于这个例子我接受了#34;:visible&#34;适用于大多数常见情况。
我用它来检查一个页面是否包含可见文本(只是在body元素上运行它),但它也可能适用于这个例子。
答案 5 :(得分:0)
不是隐藏跨度,而是删除span元素并保留对它的引用。当用户单击切换按钮时,删除另一个并插入您保留引用的那个按钮。用户将无法再选择不在DOM中的内容。