使用jQuery查找文本元素

8

我希望创建一个数组,其中包含div中包含文本字符串的所有html元素,例如

<p>some string</p>.  

我不想拿到字符串,我想要数组项成为元素(在本例中,将是p节点)。我事先不知道字符串会是什么,所以无法寻找匹配的字符串值。我也不希望空文本节点出现在数组中。
谢谢!
8个回答

11
$("#my_div *").filter(function()
{
     var $this = $(this);
     return $this.children().length == 0 && $.trim($this.text()).length > 0;
})

这个版本不会返回包含文本元素的父元素,只会返回最后一级的元素。

可能不是最快的方法,但在 StackOverflow 主页上表现得相当不错 :)


1
经过我的测试,这是一个仅返回包含文本元素而不包括其父元素的解决方案。谢谢! - Tim Sheiner
1
$('*:not(:has(*))') 可能是选择无子节点(叶子节点)的更好方法... 绝对少打字。 - Dave
当包含文本的元素具有不包含该文本的子元素时,此解决方案会中断。仅在包含文本的元素没有其他子元素时才起作用。 - Dingredient

7

在您的情况下,自定义选择器可能会很有帮助:

jQuery.expr[':'].hasText = function(element, index) {
     // if there is only one child, and it is a text node
     if (element.childNodes.length == 1 && element.firstChild.nodeType == 3) {
        return jQuery.trim(element.innerHTML).length > 0;
     }
     return false;
};

在此之后,您可以简单地执行以下操作:
$('#someDiv :hasText') // will contain all elements with text nodes (jQuery object)
$('#someDiv :hasText').get() // will return a regular array of plain DOM objects

我假设您只想选择仅包含文本的元素。

1
很好的答案,只有一个小错别字——应该检查nodeType而不是nodeValue... - John Foster

2
您可以使用not和空选择器来获取非空元素,而将其转换为数组可以使用get函数实现。
$("#theDiv > :not(:empty)").get();

上述选择器获取“theDiv”的所有子元素,但不包括空元素(即它们具有子元素或文本),然后将匹配集转换为数组。
如果您只想要包含文本的元素,则应该使用以下代码...
$("#theDiv > :not(:empty, :has(*))").get();

为了去除带有空格的元素,您可以使用过滤器。
$("#theDiv > :not(:has(*))").filter(function() { 
                 return $.trim(this.innerHTML).length > 0;
         }).get();

1
如果他想要仅包含文本的元素,则此方法将无法正常工作。此外,此方法还会返回任何具有子元素的元素,即使这些子元素中没有一个包含文本。 - TM.
1
另外需要注意的是,这只适用于 div 的直接子元素(不确定是否符合预期行为)。删除 > 可以检查所有祖先元素。在这种情况下,* 也没有任何作用。 - TM.
关于仅选择具有文本的元素进行更新。感谢您注意到 *,我已相应地更新了我的答案。 - John Foster
下降选择器几乎正确,但它也会选择具有空(全部为空格)文本节点的元素。 - TM.
这个让我有点难倒了 :). 我只是试图找到一种一行代码的方法来完成它,而不需要使用闭包(后续调用 filter 将会去除带有空格的元素)或自定义选择器。 - John Foster

1
var array = [];
var divSelector = "div.mine";

$(divSelector).contents().each(function()
{
   // If not an element, go to next node.
   if (this.nodeType != 1) return true;       

   var element = $(this);
   if ($.trim(element.text()) != "")
     array.push(element);
});

array 是包含一些文本元素的数组。


1
你可以循环遍历children并获取所有具有.text()!=“”的内容。

听起来是个好计划,但我不太了解jQuery,无法理解如何构建语法以实现您所描述的功能。您能提供一个例子吗?谢谢。 - Tim Sheiner

0

d 是您想要查找内容的 div 元素
v 是一个空数组
i 必须从 0 开始。

$.trim 用于避免获取到只包含空格的节点。

$("*",d).filter( function() { 
     return $.trim($(this).text()) != ""
  } ).each( function() { 
     v[i] = $(this).text(); 
     i++; 
  } );

还可以使用v.push($(this))...这是我完全忘记了的事情。


这看起来很有前途,我会尝试一下。如果我只想要元素,而不是实际文本,那么最终赋值是否为: v[i] = $(this); - Tim Sheiner
这取决于你想让它成为一个jQuery对象还是不想。如果你想要它成为一个jQuery对象,那么它就是$(this)。如果你只想要DOM元素,那就只需使用this。 - Thomas
实际上,你甚至不需要这样做...你只需要删除.each(),因为它的唯一目的是提取文本。(抱歉,在我发表最后一条评论时我有些分心。) - Thomas

0
 $(function() {
        var array = new Array();
        $("#testDiv *").each(function(x, el) {

            if ($.trim($(el).text()) != '' ) {
                array.push(el);
            }
        });
        alert(array.length);
    });

0
使用 :contains 选择器:
var matches = new Array();
$('#start_point *:contains(' + text + ')').each(function(i, item) {
 matches.push( item );
}

他说他没有任何特定的文本要搜索。 - TM.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接