一个直接包含文本的元素的jQuery选择器?

时间:2011-10-25 22:04:28

标签: javascript jquery

我能够使用:contains选择器使其部分工作,但我的问题是,如果元素包含一个包含仍然返回的文本的元素。例如:

$('div:contains("test")')

将选择以下两个div:

<div>something else
   <div>test</div>
</div>

小提琴:http://jsfiddle.net/TT7dR/

如何只选择“直接”包含文字的div?这意味着在上面的例子中只会选择子div。

更新

只是为了澄清,如果我在搜索“别的东西”而不是“测试”,那么我只想找到父div。

10 个答案:

答案 0 :(得分:11)

$('div>:contains("test")')不是一般解决方案,它仅适用于您的具体示例。它仍然匹配其后代包含文本test的任何元素,只要其父级是div

实际上目前没有选择器只会选择包含目标文本的文本节点的直接父项。要做到这一点,你必须自己走DOM树,检查你找到的目标文本的每个文本节点,或者写一个插件来做同样的事情。它会很慢,但不会像:contains那么慢(它不是标准的CSS选择器,所以你不能获得浏览器本地的快速选择器支持)。

这是一个可以用作起点的普通DOM函数。可以改进在相邻(非规范化)文本节点中查找文本,或者将其隐藏在插件/选择器扩展中。

function findElementsDirectlyContainingText(ancestor, text) {
    var elements= [];
    walk(ancestor);
    return elements;

    function walk(element) {
        var n= element.childNodes.length;
        for (var i= 0; i<n; i++) {
            var child= element.childNodes[i];
            if (child.nodeType===3 && child.data.indexOf(text)!==-1) {
                elements.push(element);
                break;
            }
        }
        for (var i= 0; i<n; i++) {
            var child= element.childNodes[i];
            if (child.nodeType===1)
                walk(child);
        }
    }
}

答案 1 :(得分:5)

只是为了完成知识库。如果您需要获取包含特定文本或字符的正文中的所有DOM元素(不仅仅是DIV),您可以使用:

function getNodesThatContain(text) {
    var textNodes = $(document).find(":not(iframe, script)")
      .contents().filter( 
          function() {
           return this.nodeType == 3 
             && this.textContent.indexOf(text) > -1;
    });
    return textNodes.parent();
};

console.log(getNodesThatContain("test"));

希望有所帮助。

jsfiddle:http://jsfiddle.net/85qEh/2/

致谢:DMoses

答案 2 :(得分:4)

您可能必须执行无效查询。如果有人找到设法过滤掉子元素的选择器,请不要使用此解决方案:http://viralpatel.net/blogs/2011/02/jquery-get-text-element-without-child-element.html

$("div:contains('test')")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .filter(":contains('test')")

修改:上面的代码片段只是为了测试元素,在实现中它看起来更像是这样:http://jsfiddle.net/rkw79/TT7dR/6/

$("div:contains('test')").filter(function() {
    return (
    $(this).clone() //clone the element
    .children() //select all the children
    .remove() //remove all the children
    .end() //again go back to selected element
    .filter(":contains('test')").length > 0)
}).css('border', 'solid 1px black');

答案 3 :(得分:3)

尝试添加大于:

$('div>:contains("test")')

答案 4 :(得分:0)

这似乎对我有用:

$('div >:contains("test")');

http://jsfiddle.net/TT7dR/1/

这会强制匹配的:contains选择器成为<div>元素的直接子元素

答案 5 :(得分:0)

尝试以下方法:

$("div>div:contains(test):only-of-type")

答案 6 :(得分:0)

查找特定元素,但不查找父母

var elementsContainingText = ($(':contains("' + text + '")', target)).filter(function() {
    return $(this).contents().filter(function() {return this.nodeType === 3 && this.nodeValue.indexOf(text) !== -1; }).length > 0;
});

答案 7 :(得分:0)

添加更多替代方案:

var str = "Hello, playground"
var strs = ["abc","def"]

print(str)
print(strs, separator: ",", terminator: "")
print(str, separator: ",", terminator: "\n")

它将仅选择文本并删除任何带标记的元素!

Reference

答案 8 :(得分:0)

您只需选择不包含您元素的元素

$('div:contains("test"):not(:has(> div))')

答案 9 :(得分:0)

更少的代码编写(但有一些限制):

let selector = $('div:contains("test")');
selector.not(selector.has('div:contains("test")'))

只需使用jQuery函数(.has),因为CSS :has是实验性的: https://developer.mozilla.org/en-US/docs/Web/CSS/:has#Browser_compatibility


限制条件:

当您具有这样的结构时:

<div>
<div>test</div>
test
</div>

然后,此解决方案将只找到内部div-元素。这是因为仍然有一个元素-div的子元素:包含字符串“ test”。