我的印象是closest()
会给我最接近的匹配元素,但我错了,它会给我最近的祖先,parents()
也是如此。那我怎样才能得到最近的元素?
e.g。我有2 div
s,如下所示
<div id="clickme">
Click me
</div>
<div class="findme" style="display:none">
Find me
</div>
如果我想通过.findme
引用#clickme
该怎么办。
我可以执行$('#click').helpfullFunctionThatGivesNearestElement('.findme')
之类的操作吗?
或者我是否需要像$('findme')
那样扫描整个DOM?但是可以有100个.findme
那么我怎样才能找到最接近特定元素的东西?
更新
.findme
可以在DOM中的任何位置。
答案 0 :(得分:2)
这是递归遍历DOM的方式。
我已经实现了函数 $.fn.nearest
,因为OP可以使用jQuery,因此可以使用$('clickme').nearest('.findme');
该方法将通过递归搜索找到多个元素**(如果它们与起始节点共享相同的距离),通过向各个方向(父,子,下一个和上一个)向前和向后看通过最近的选中元素。它还避免反复检查元素(即只检查多个子元素的父元素)。
如果您不需要检查特定方向,即children
或prev
,您只需评论该部分。
在递归完成之前进行一些检查。当在DOM中找不到选择器时,返回一个空的jQuery元素,当只有一个元素被找到时,返回找到的元素。
我没有使用大型HTML测试它的效率,这完全取决于所需元素的位置,这与HTML结构的复杂性直接相关。但肯定它是指数级的,接近O(n³)或O(n⁴)。
试一试。
$.fn.nearest = function(selector) {
var allFound = $(selector);
if (!allFound.length) // selector not found in the dom
return $([]);
if (allFound.length == 1) // found one elem only
return allFound;
else
return nearestRec($(this), selector);
function nearestRec(elems, selector) {
if (elems.length == 0)
return this;
var selector = selector;
var newList = [],
found = $([]);
$(elems).each(function(i, e) {
var options = e[1] || {};
e = $($(e)[0]);
// children
if (!options.ignoreChildren)
updateFound(e.children(), selector, newList, found, {
ignoreParent: true
});
// next
if (!options.ignoreNext)
updateFound(e.next(), selector, newList, found, {
ignoreParent: true,
ignorePrev: true
});
// prev
if (!options.ignorePrev)
updateFound(e.prev(), selector, newList, found, {
ignoreParent: true,
ignoreNext: true
});
// parent
if (!options.ignoreParent)
updateFound(e.parent(), selector, newList, found, {
ignoreChildren: true
});
});
return found.length && found || nearestRec(newList, selector);
function updateFound(e, selector, newList, found, options) {
e.each(function() {
var el = $(this);
if (el.is(selector)) {
found.push(el);
return;
}
newList.push([el, options]);
});
}
}
};
$(function() {
// multiple elems found, traverse dom
$(".clickme").nearest(".findme").each(function() {
$(this).addClass("found");
});
});
div {
padding: 5px 3px 5px 10px;
border: 1px solid #666;
background-color: #fff;
margin: 3px;
}
.found {
background-color: red;
}
.clickme {
background-color: #37a;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="findme">
findme
<div class="findme">
findme
<div>
<div>
</div>
<div>
</div>
<div class="clickme">
clickme
<div>
</div>
<div>
<div class="findme">
findme
<div class="findme">
findme
</div>
</div>
<div class="findme">
findme
</div>
</div>
</div>
<div>
<div class="findme">
findme
</div>
</div>
<div class="findme">
findme
</div>
</div>
<div class="findme">
findme
<div>
</div>
<div>
</div>
<div class="findme">
findme
<div class="findme">
findme
</div>
</div>
<div>
</div>
<div class="findme">
findme
</div>
</div>
</div>
</div>
答案 1 :(得分:0)
jquery插件:
$('#clickme').nextElementInDom('.findme');
<强>用法:强>
android:descendantFocusability="blocksDescendants"
答案 2 :(得分:-1)
您可以尝试通过引用其封闭父级来定位元素,而不是遍历整个DOM树。
<div>
<div id="clickme" onclick="$(this).parent().find('.findme').show();">
Click me
</div>
<div class="findme" style="display:none">
Find me
</div>
</div>
但是,只有当您搜索的元素具有相同的祖先父级时,这才有效。