代码之家  ›  专栏  ›  技术社区  ›  Gazzer

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

  •  15
  • Gazzer  · 技术社区  · 16 年前

    我有一个网站,转换 Japanese Kanji into Romaji (roman letters)

    输出会根据用户的输入条件,使用CSS显示和隐藏用户需要看到的内容。例如:

    <div id="output"><span class="roman">watashi</span> <span class="english">I</span></div>

    该界面允许用户在和的输出之间切换 watashi I

    问题是,当用户将文本复制/粘贴到Word中时,它会复制所有内容。因此,我决定使用一个系统,使用JavaScript和jQuery复制粘贴文本,但问题再次出现:

    $('#output').text() 输出 watashi I 瓦塔希

    6 回复  |  直到 5 年前
        1
  •  17
  •   TylerH Ash Burlaczenko    5 年前

    使用 :visible selector of jQuery

    在你的情况下,我认为你应该:

    $('#output').children(":visible").text() 
    
        2
  •  25
  •   guy mograbi    10 年前

    其他的解决方案并没有满足我的需要。

    我的答案是:

    $('#output *:not(:has(*)):visible').text()
    

    plunkr

    TL;博士

    您不应该询问某个根元素下所有元素的文本。。

    为什么它将重复输出并忽略隐藏标志

    <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 .. .某个部门

    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>
    
        some text here.. 
    
    <div>
    

    为什么这个假设在我看来是合理的?原因有二:

    • 将html转换为这种结构很容易。只需用跨距将父文本换行即可。因此,即使这个假设现在不存在,也很容易实现。

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

    $('#输出*:不(:has(*):visible')。text()
    

    这将产生正确的结果。

    必须在叶元素之外有文本?

    这些评论建议,有时您只需要在叶元素之外添加文本

    <div> This is some <strong style="display:none"> text </strong>  </div>
    

    正如你所看到的,你有 <strong> 作为一个叶子,在它外面有文本是很常见的,就像在这个例子中一样。

    你可以用我上面建议的解决方法来解决这个问题。。但是如果你不能呢?

    这里的问题是为了 :visible 选择器或 :hidden 所以,这种方法有一些副作用,所以要小心。

    这里有一个例子

    对于此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

    如前所述-副作用可能会出现短暂的闪烁,或者一些应该运行的初始化脚本。。根据您的场景,可以通过一些独创性的想法(大小为1px/1px的div将克隆与原始内容一起包含?)来避免某些情况。

        3
  •  10
  •   aehlke    5 年前

    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;
    }
    

    然后:

    getVisibleText(document.getElementById('output'));
    
        4
  •  2
  •   Stephen McFarland    10 年前

    盖伊有正确的答案。

    $('*:not(:has(*)):visible', this).text()
    
        5
  •  1
  •   Community Mohan Dere    9 年前
    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 ,但对于本例,我接受“:visible”适用于大多数常见情况。

        6
  •  0
  •   Kaze no Koe    16 年前

    删除跨度图元并保留对其的引用,而不是隐藏跨度。当用户单击切换按钮时,移除另一个按钮并插入您保留引用的按钮。用户将无法选择不再在DOM中的内容。