如何使用JQuery(或Javascript)获取可见文本

Gaz*_*zer 18 javascript jquery

我有将日语汉字转换成罗马字母(罗马字母)的网站:

并且输出显示和隐藏CSS用户需要根据其输入条件查看的内容.例如:

<div id="output">
    <span class="roman">watashi</span> 
    <span class="english">I</span>
</div>
Run Code Online (Sandbox Code Playgroud)

该接口允许用户之间的输出翻转watashiI取决于他们想看到的.

CSS生皮的一个或另一个使用jQuery和切换按钮.(隐藏机制涉及简单地添加一个类body并让它CSS做它的事情).

问题是,当用户将文本复制/粘贴到Word其中时,复制所有内容.所以我决定使用系统来复制使用JavaScript和粘贴文本jQuery,但问题重复:

$('#output').text()
Run Code Online (Sandbox Code Playgroud)

输出watashi I即使I在页面本身不可见而不是watashi.有没有办法获得可见的文字?

guy*_*abi 20

其他解决方案没有给我我需要的东西.

简答

我的回答是:

$('#output *:not(:has(*)):visible').text()
Run Code Online (Sandbox Code Playgroud)

plunkr

TL; DR

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>
<div>
Run Code Online (Sandbox Code Playgroud)

现在,如果我这样做 $('#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>
Run Code Online (Sandbox Code Playgroud)

为什么这个假设对我来说似乎合理?两个原因:

  • 因为很难维护以这种方式构建的页面 - 并且随着时间的推移,有经验的人会学习并避免它.
  • 很容易将您的html转换为这样的结构.用跨度包装父母的文本.因此,即使现在不存在这种假设,也很容易实现.

根据这个假设,你想要做的是请求所有叶元素(没有子元素的元素),过滤掉可见元素,并询问它们的文本.

$('#output *:not(:has(*)):visible').text()
Run Code Online (Sandbox Code Playgroud)

这应该产生正确的结果.

叶元素外面有文字吗?

评论建议有时你只需要在leaf元素之外有文本

<div> This is some <strong style="display:none"> text </strong>  </div>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,您有<strong>一个叶子,并且通常在此示例中包含文本.

您可以使用我上面建议的解决方法解决它...但是如果你不能怎么办?

您可以克隆dom,然后删除所有隐藏的元素.这里的问题是,为了使:visible选择器或:hidden选择器工作,我必须在文档上有dom元素(这意味着用户实际可见).因此,这种方法会带来一些副作用,所以要小心.

这是一个例子

对于这个HTML

 <div id="output" class="my-root">
     <span>
         some text <strong style="display:none">here.. </strong>
     </span>
</div>
Run Code Online (Sandbox Code Playgroud)

这个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. 
})
Run Code Online (Sandbox Code Playgroud)

看到这里的plunker

如上所述 - 副作用可能看起来像一个瞬间闪烁,或一些应该运行的初始化脚本..有些原始思维(div大小为1px/1px以包含克隆和原始内容?)可能会避免一些,具体取决于您的方案.


mar*_*cgg 12

使用Jquery:visible选择器

在你的情况下,我认为你想做:

$('#output').children(":visible").text() 
Run Code Online (Sandbox Code Playgroud)


Van*_*Dir 10

在现代浏览器中试试这个(这里的“元素”是一个非 JQuery DOM 对象):

function getVisibleText(element) {
    window.getSelection().removeAllRanges();

    let range = document.createRange();
    range.selectNode(element);
    window.getSelection().addRange(range);

    let visibleText = window.getSelection().toString().trim();
    window.getSelection().removeAllRanges();

    return visibleText;
}
Run Code Online (Sandbox Code Playgroud)

然后:

getVisibleText(document.getElementById('output'));
Run Code Online (Sandbox Code Playgroud)