繁体   English   中英

使用jQuery和CSS Selector选择嵌套元素的公共父/祖先

[英]Select common parent/ancestor of nested elements with jQuery and CSS Selector

我期待选择多个嵌套元素的共同父元素,我只知道内部文本。

例如,在以下代码中:

<unknown>       
    <unknown class="unknown">
        ....
        <unknown>
            <unknown>Sometext</unknown>
        </unknown>
        <unknown>
            <unknown>Sometext</unknown>
        </unknown>
        <unknown>
            <unknown>Sometext</unknown>
        </unknown>
        ....
    </unknown>
</unknown>

我想获得在这种情况下具有类未知的最接近元素(共同父元素)。 我不知道实际的标签或类名。 我只知道nest元素包含“Sometext”。 我知道这可以通过使用jQuery / Javascript的循环完成,但是有一个CSS选择器,我可以使用jQuery来找到它吗? 我尝试使用nearest(),parents(),parentsUntil()的组合,但我似乎无法得到这个元素。

谢谢!

首先,您需要确保只匹配叶节点(没有子节点的节点),因此使用:

:not(:has(*))

因此,要查找所有完全匹配(只是叶节点),请使用:

var matches = $(':not(:has(*))').filter(function () {
    return $(this).text() == "Sometext";
});

或者只对所有元素使用组合过滤器(添加0个孩子的检查):

var matches = $('*').filter(function () {
     return !$(this).children().length && $(this).text() == "Sometext";
});

注意: 我还没有测试过这两个选项中哪一个最快。

然后你需要找到包含所有匹配的第一个祖先(第一个匹配):

var commonparent = matches.first().parents().filter(function () {
    return $(this).find(matches).length == matches.length;
}).first();

JSFiddle: http //jsfiddle.net/TrueBlueAussie/v4gr1ykg/

根据David Thomas的建议,这里有一对jQuery扩展( commonParents()commonParent() ),可能会在以后用于人们:

要查找jQuery集合的所有常见父项,请使用`commonParents()':

$.fn.commonParents = function (){
    var cachedThis = this;
    return cachedThis.first().parents().filter(function () {
        return $(this).find(cachedThis).length === cachedThis.length;
    });
};

JSFiddle :( commonParents): http //jsfiddle.net/TrueBlueAussie/v4gr1ykg/3/

要查找jQuery集合中最接近的公共父级,请使用commonParent()

$.fn.commonParent = function (){
    return $(this).commonParents().first();
};

JSFiddle :( commonParent): http //jsfiddle.net/TrueBlueAussie/v4gr1ykg/2/

笔记:

  • jQuery优化了commonParentfirst()commonParents filter()的组合使用,它只调用commonParents的代码, 直到第一次匹配为止 ,因此不需要使commonParent更高效。

这应该做的工作。 你基本上找到了所有匹配元素的所有相关父元素,得到每个集合的交集,然后抓住第一个集合来获得最嵌套的公共父元素。

您甚至可以像jquery插件一样将其打包。

 if(console && console.clear) console.clear(); // create a handy intersection method for Arrays // see http://stackoverflow.com/a/16227294/1901857 Array.prototype.intersect = function(arr) { var a = this, b = arr; var t; if (b.length > a.length) t = b, b = a, a = t; // indexOf to loop over shorter return a.filter(function (e) { return b.indexOf(e) > -1; }); }; ;(function($) { $.fn.commonParents = function(selector) { // find all relevant parents for each element and get set intersection // pushStack means you can use end() etc in chaining correctly return this.pushStack(sometexts.get().reduce(function(prevParents, el) { // common parents for this element - note the lowest level parent is first var parents = $(el).parents(selector || '*').get(); // intersect with the previous value (or itself if first) return (prevParents || parents).intersect(parents); }, null), "commonParents", arguments); }; })(jQuery); // text to search for var search = "Sometext"; // parent selector to filter parents by eg '.unknown' - use null for all parents var parentSelector = null; // find everything containing search var sometexts = $(":contains('" + search + "')").filter(function() { return $(this).text() == search; }); // grab the first common parent - the lowest level one - or null if there isn't one var commonParent = sometexts.commonParents(parentSelector).get(0); console.log(commonParent); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <div class="unknown test"> <div class="unknown test2"> <div class="unknown"> <div>Sometext</div> </div> <div> <div>Sometext</div> </div> <div> <div>Sometext</div> </div> </div> </div> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM