问题:给定一个特定的容器dom元素(窗口,div,字段集等),在该DOM元素中查找类(.FormWidget)的所有元素,以递归方式搜索所有元素那个容器的后代。包含,但不要查看,具有匹配类(.FormWidget)的元素。元素可以嵌套到 n 级别。
例如,给定此HTML:
<fieldset id="MyFieldset" class="FormWidget FieldSetMultiplier">
<legend>My Legend</legend>
<div>
<label for="Field1">Field1</label>
<input type="text" name="Field1" value="" id="Field1" class="BasicInput FormWidget">
</div>
<div id="SomeWidget" class="FormWidget">
<label for="Field2">Field2</label>
<div name="Field2" id="Field2" class="FormWidget RestrictedComboBox"></div>
<input type="text">
</div>
</fieldset>
<div>
<label for="Field3">Field3</label>
<input type="text" name="Field3" value="" id="Field3" class="BasicInput FormWidget">
</div>
示例1:
让伪Jquery函数&#34; .findButNotInside()&#34;代表我正在寻找的功能。
$(document).findButNotInside('.FormWidget');
只应返回#MyFieldset和#Field3。从窗口开始,字段1和2以及#SomeWidget是FormWidgets,但它们不能被包括在内,因为不允许该函数查看其他.FormWidgets以查找FormWidgets。 .FormWidget字段集中的任何内容都是禁止的。
示例2:
$('#MyFieldset').findButNotInside('.FormWidget');
应仅返回#Field1
和#SomeWidget
。应该查找目标字段集.FormWidget
内的#MyFieldset
,但不应返回#Field2,因为不允许查看.FormWidget(在本例中为#SomeWidget)内部找到其他.FormWidgets。
我认为这可以通过正确的功能和选择器来完成,但我不确定应该如何构建选择器?
答案 0 :(得分:5)
$.fn.findButNotInside = function(selector) {
var origElement = $(this);
return origElement.find(selector).filter(function() {
var nearestMatch = $(this).parent().closest(selector);
return nearestMatch.length == 0 || origElement.find(nearestMatch).length == 0;
});
};
Fiddle。诀窍是检查nearestMatch
实际上是否在我们的搜索环境中。
请注意这个无效:
$('window').findButNotInside('.FormWidget');
...因为没有<window>
标记。你想要的是:
$(document).findButNotInside('.FormWidget');
答案 1 :(得分:1)
$("container-selector").find(".class").not(".class .class");
答案 2 :(得分:0)
此解决方案依赖于有关HTML结构的已知信息:
$('body .FormWidget').filter(function(){
return $(this).parents('.FormWidget').length == 0;
}).css("border", "solid 3px red");
$('#MyFieldset .FormWidget').filter(function(){
return $(this).parents('.FormWidget').length == 1;
}).css("border", "solid 3px blue");
答案 3 :(得分:0)
想不出更优雅的“jquery ish”解决方案。但是,这可以递归地完成。
function findIt($elements){
$elements.children().each(function(i){
var $this = $(this);
if($this.is(".FormWidget")){
// do something with the matched element
$this.css("border","1px solid red");
}else{
// make the recursive call
findIt($this);
}
});
}
findIt($("#MyFieldset"));
你显然可以把它变成一个插件。
答案 4 :(得分:0)
(function($){
$.fn.findButNotInside = function(selector){
var _n,_o,elemArr=[];
this.find('.FormWidget').each(function(){
_o = _n;
_n = $(this);
try{
if(_o&&_o.find(_n).length){
_n = _o;
if(elemArr.indexOf(_o)==-1) throw _o;
}else throw _n;
}catch(e){
elemArr.push(e);
}
});
return $().add(elemArr);
}
})(jQuery);