【问题标题】:Get only visible text with jquery仅使用 jquery 获取可见文本
【发布时间】:2013-07-19 05:08:11
【问题描述】:

假设我有一些这样的 html:

<div id="content">Foo<span style='display:none'>hidden</span>Bar</div>

实际上,这更复杂,并且是由 Angular 使用 ng-hide 和类似方法生成的。我需要从用户可见的content div 中获取所有文本。在这种情况下,我想得到FooBar

$('#content').text() 是我找到的最接近的东西,但在这种情况下这给了我FoohiddenBar。有没有一种只获取 div 的可见内容的好方法?我真的需要一个跳过隐藏元素的text() 函数。

【问题讨论】:

    标签: jquery html angularjs


    【解决方案1】:

    创建一个克隆,将其添加到 DOM(正如 slindberg 所指出的),删除所有隐藏元素,然后获取文本:

    var clone = $('#content').clone();
    
    clone.appendTo('body').find(':hidden').remove();
    
    var text = clone.text();
    
    clone.remove();
    

    FIDDLE

    【讨论】:

    • 这在示例中有效,但在我的实际应用中,整个输出 div 由复杂的角度标签组成。几乎所有东西都会被clone.find(':hidden').remove(); 删除,甚至是可见的项目。很有趣。
    • 如果它不是有效的标记,但由于某种原因包含角度标签,并且无法使用常规的 DOM 遍历方法进行解析,那么您就有问题了。
    • 由于某种原因,clone.find(':hidden') 返回的集合比$('#content').find(':hidden') 大得多,这都是有效的标记。也许是因为 angular 没有完全编译克隆的元素?
    • 可能,我对 angular 真的不是很熟悉!
    • 除了使用 ng-hide 之外,我还通过 Angular 应用 showhide 类使其工作。 find('.hide') 在我看来似乎更可靠。
    【解决方案2】:

    不幸的是,@adeneo 的答案在大多数情况下都不起作用,因为克隆会创建一个文档片段,其子项根据定义是不可见的(它们没有附加到文档中),因此在调用 .text() 之前全部被删除。这意味着元素的子元素的文本不会包含在结果中。

    我发现这样做的唯一方法是实际上自上而下遍历所有节点,省略视觉上隐藏的节点。幸运的是,这可以用一个相当简洁的插件来表达:

    jQuery.fn.visibleText = function() {
      return $.map(this.contents(), function(el) {
        if (el.nodeType === 3) {
          return $(el).text();
        }
        if ($(el).is(':visible')) {
          return $(el).visibleText();
        }
      }).join('');
    };
    

    请注意,此插件假定选择器的根元素不是文本节点(几乎从来不是这种情况)。另请注意,如果您不必支持 IE8,则可以将 $(el).text() 替换为 el.textContent

    JSFiddle

    【讨论】:

    • 行不通是什么意思?您是否在我的回答中尝试过 Fiddle,它似乎工作得非常好,那是因为 jQuery 的 :visible 伪选择器不关心元素是否在 DOM 中。
    • 问题是从克隆中删除:hidden 元素最终会删除所有子元素,因为当它们与文档根目录分离时,它们都被认为是隐藏的。我创建了 a fork of your JSFiddle 来演示这个问题。我已经更新了我的答案,以便更清楚地了解这个问题。
    • 我明白你的意思,在这种情况下,这无关紧要,但如果有人有其他元素等可能很重要。我实际上也在文档中找到了它,"Elements不在文档中的不被认为是可见的”,这点很好。我更改了答案以修复它。
    【解决方案3】:

    诀窍是修改 DOM 以获取文本,然后在完成后将其恢复为原始状态。以下是诀窍:

    function get_visible_text(content) {
        // Not so easy to get the visible text
        var saved = $(content).clone();
        // Remove the hidden parts
        $(content).find(':hidden').remove();
        // Get the remaining text
        var visible_text = $(content).text();
        // Now revert back to our saved version
        $(content).replaceWith(saved);
        return visible_text;
    }
    

    请注意@slindberg 是正确的,@adeneo 的答案将不起作用,因为克隆的对象在插入 DOM 之前是不可见的。通过就地修改 DOM,我们避免了这个问题。

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多