我正在尝试在单击内部嵌套按钮时关闭父容器。在我的UI中 - 我有许多这些父容器(我在产品类别页面上渲染产品目录的预览窗口)。
从下面的标记中可以看出 - CLOSE按钮深深嵌套在DOM中。当用户点击CLOSE按钮时 - 我需要隐藏()父Box-1。请记住,我可能一次在页面上显示最多100个产品(100盒“Box-1”)。
我的标记看起来像这样:
<div class="box-1">
<div class="box-2">
<div class="box-3">...</div> <!-- end box-3 -->
<div class="box-4">
<div class="box-5">...</div> <!-- end box-5 -->
<a class="btn-close" href="#">CLOSE</a> <!-- this triggers the close event -->
</div> <!-- end box-4 -->
</div> <!-- end box-2 -->
<div class="box-6">
<div class="box-7">...</div> <!-- end box-7 -->
<div class="box-8">
...
<div class="box-9">...</div> <!-- end box-9 -->
</div> <!-- end box-8 -->
</div> <!-- end box-6 -->
</div> <!-- end box-1 -->
我的问题是 - 我如何最好(并且最有效)遍历DOM以获取“box-1”并发出.hide()方法......这是我现有的代码。
<script>
$productsResultItems.delegate('.btn-close', 'click', function (e) {
//box-1
$(this).parents('div.box-1').hide(); // <-- is this the best way?????
e.preventDefault();
</script>
最初,我正在尝试这个 -
$this.parents().find('.hover-box-large').hide();
在IE7和IE8中被证明非常慢。
我发现添加更多细节到选择器改进了IE7的性能近100倍,但IE8只增加了4倍:( IE8仍然需要大约200ms来关闭父容器。现在所有其他浏览器(Chrome,Safari) ,Firefox和IE7)在不到20ms的时间内关闭容器。
$this.parents('div.hover-box-large').hide();
但是有更好的选择器方法吗?任何特殊原因IE8在这种类型的向上遍历都太糟糕了吗?
答案 0 :(得分:5)
使用的最佳方法是closest
,它会找到与选择器匹配的最近的祖先元素:
$this.closest('div.box-1').hide();
答案 1 :(得分:3)
实际上.closest()
应该比.parents()
更快。
在jQuery Docs on .closest()
中,您可以找到:
.closest()
- 从当前元素开始
- 向上移动DOM树,直到找到所提供选择器的匹配项
- 返回的jQuery对象包含零个或一个元素
<强>。家长()强>
- 从父元素开始
- 将DOM树移动到文档的根元素,将每个祖先元素添加到临时集合中;然后过滤它 基于选择器的集合(如果提供了一个
)- 返回的jQuery对象包含零个,一个或多个元素
所以在你的情况下,.closest()
将是最合适的一个,因为你需要找到一个元素,最接近你的选择器的祖先。 parents()
将过滤掉所有可能的祖先元素,即使它已经找到了你需要的元素。
答案 2 :(得分:1)
parent()和nearest()之间的唯一区别是,一旦找到匹配,nearest()就会停止,因此总是返回0或1个元素。 Parents()将匹配DOM的所有内容。
$(this).closest('.box-1').hide();
答案 3 :(得分:0)
不是那么快! closest()
可能是最好的,但并非总是如此!以下是您如何找到自己的方法。使用Firebug time() and timeEnd()功能实际记录您的呼叫。然后选择适合该情况的那个。
// 59ms
console.time("Parent x 3");
$container = $element.parent().parent().parent();
console.timeEnd("Parent x 3");
// 3ms
console.time("Closest parent");
$container = $element.closest('.some-class').parent();
console.timeEnd("Closest parent");
// 2ms
console.time("Parents");
$container = $element.parents('.other-class').eq(1);
console.timeEnd("Parents");