我希望选择多个嵌套元素的公共父级,我只知道内部文本。
例如,在以下代码中:
<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()的组合,但我似乎无法使用此元素。
谢谢!
答案 0 :(得分:3)
首先,您需要确保只匹配叶节点(没有子节点的节点),因此请使用:
: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&#39;建议,这里它是一对jQuery扩展(commonParents()
和commonParent()
),可能将来会用于人们:
要查找jQuery集合的所有常见父项,请使用`commonParents()&#39;:
$.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/
注意:
first()
commonParent
与commonParents
filter()
的合并使用,并且只调用commonParents
中的代码,直到进行了第一场比赛,因此commonParent
不需要提高效率。 答案 1 :(得分:0)
这应该可以胜任。你基本上找到了所有匹配元素的所有相关父元素,得到每个集合的交集,然后抓住第一个集合来获得最嵌套的公共父元素。
您甚至可以像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 e.g. '.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>