是否有任何类似于nearest()的jQuery函数会返回父链外的元素,横向移动?例如,我想在div源上调用一个函数foo()来返回div目标。我知道我可以使用parent()和siblings()进行导航,但是我需要一些通用的东西,可以根据需要,向上,向侧面和向下进行多个级别?
var allsources = $('.source');
allsources.click(function()){
$(this).closest('.target').hide();
});
<div class="row">
<div>
<div class="target" ></div>
</div>
<div>
<div>
<div class="source"></div>
</div>
</div>
</div>
<div class="row">
<div>
<div class="target" ></div>
</div>
<div>
<div>
<div class="source"></div>
</div>
</div>
</div>
编辑:
我对最接近的定义:你有一个元素来源。试着找到它。如果找到多个,则返回一个较少的节点箍/下一个/上一个。如果找不到,请向上一级,然后再次尝试查找。重复直到没有父母。
答案 0 :(得分:5)
如果,最近,你的意思是“尽可能少地往前走”,那么你可以做到
$("#source")
.closest(":has(.target)")
.find(".target:first") //make sure we only select one element in case of a tie
在您的情况下,最好直接指定公共父级:
$(this)
.closest(".row")
.find(".target") //there's no tie here, no need to arbitrate
答案 1 :(得分:2)
这是一个棘手的问题。正如已经评论过的,在这种情况下如何定义最接近的?假设你可以决定一些规则;例如:
遍历:3pt
横穿:2分
横向移动:1pts
然后将具有最低点的项目视为“最接近”,然后创建一个名为closestAll
的名称的插件就足够了,它会对整个dom树进行递归遍历。确定最近的项目。
然而,看看你最近的编辑,一个(很多!)正确的解决问题的方法是:
var allsources = $('.source');
allsources.click(function(){
$(this).parents('.row').find('.target').hide();
});
实例:http://jsfiddle.net/zCvJM/(来源A仅隐藏目标A,B代表相同)
答案 2 :(得分:2)
如果您确切知道dom的结构和嵌套级别,您是否考虑使用eq()方法
$(this).parents().eq(1).prev().children(".target")
答案 3 :(得分:1)
除了基本上查询整个DOM之外,我认为没有办法做到这一点:
$('#target')
因为如果你想要越过(也不要介意),那么目标元素与子元素无关。如果您还想检查是否存在子元素,则必须单独执行此操作。
的 - 编辑:强> 的
在阅读你想要找到最接近的元素的评论后,无论它是否是父母,我认为你必须编写一个自定义函数来一次抓取一个dom节点。我测试了以下内容并且有效:
<强>标记强>
<div id="parent">
<div id="child1">
<div id="source"></div>
</div>
<div id="child2">
<div class="target" rel="right"></div>
</div>
<div id="child3">
<div>
<div class="target" rel="wrong"></div>
</div>
</div>
</div>
<强>脚本强>
$(document).ready(function () {
var tgt = findClosest($('#source'), '.target');
if (tgt != undefined) {
alert(tgt.attr('rel'));
}
});
function findClosest(source, targetSel) {
var crawledNodes = $();
var target = null;
// Go up
source.parents().each(function () {
console.log(crawledNodes.index($(this)));
if (crawledNodes.index($(this)) == -1 && target == null) {
crawledNodes.add($(this));
target = findTarget($(this), targetSel);
// Go across
$(this).siblings().each(function () {
console.log("Sibling");
if (crawledNodes.index($(this)) == -1 && target == null) {
crawledNodes.add($(this));
target = findTarget($(this), targetSel);
}
});
}
});
return target;
}
function findTarget(el, targetSel) {
console.log(targetSel);
var target = el.find(targetSel);
if (target.size() > 0) {
return target.eq(0);
}
else
{
return null;
}
}
答案 4 :(得分:1)
如果我正确理解了规范,那么你的意思就像下面最接近定义的函数一样:
var allsources = $(".source");
function closest($source,selector) {
if($source == null) return $([]);
var $matchingChildren = $source.find(selector);
if($matchingChildren.length != 0) return $($matchingChildren.get(0));
else return closest($source.parent(), selector)
}
allsources.click(closest($(this),'.target').hide();});
您可以在http://jsfiddle.net/y2wJV/1/
看到它正常工作您的定义要求在匹配的子项中进行选择时,该函数必须返回一个较少的节点向下/ next / prev。这个要求还没有达到,但是这个功能非常灵活,似乎就你所提供的例子做了你想做的事。
答案 5 :(得分:0)
我发现这段代码很简单,但没有解决领带问题(返回第一个)......
(function ($) {
$.fn.findClosest = function (filter) {
var $found = $(),
$currentSet = this; // Current place
while ($currentSet.length) {
$found = $currentSet.find(filter);
if ($found.length) break; // At least one match: break loop
// Get all children of the current set
$currentSet = $currentSet.parent();
}
return $found.first(); // Return first match of the collection
};
})(jQuery);
答案 6 :(得分:0)
我遇到了类似的问题,我有一个表,我需要找到可能在当前td之外的下一个元素,所以我做了一个jquery函数:
$.fn.nextAllLevels = function(sel) {
if ($(this).nextAll(sel).length != 0) {
return $(this).nextAll(sel).eq(0);
} else if ($(this).nextAll(':has(' + sel + ')').length != 0) {
return $(this).nextAll(':has(' + sel + ')').find(sel).eq(0);
} else {
return $(this).parent().nextAllLevels(sel);
}
所以要使用它,你只需调用
$('#current').nextAllLevels('.target');
为了给你最接近前进方向的元素,无论in是否在当前的父级中。