6

单击内部嵌套按钮时,我试图关闭父容器。在我的 UI 中——我有许多这样的父容器(我在产品类别页面上呈现我的产品目录的预览窗口)。

正如您在下面的标记中看到的那样——CLOSE 按钮深深地嵌套在 DOM 中。当用户点击关闭按钮时——我需要隐藏()父 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 仍然需要大约 200 毫秒来关闭父容器。现在所有其他浏览器(Chrome、Safari、Firefox 和IE7) 在不到 20 毫秒内关闭容器。

$this.parents('div.hover-box-large').hide();

但是有没有更好的选择器方法呢?IE8在这种向上遍历方面非常糟糕的任何特殊原因?

4

4 回答 4

7

最好的方法是closest,它找到与选择器匹配的最近的祖先元素:

$this.closest('div.box-1').hide();
于 2011-06-06T14:45:22.220 回答
3

其实.closest()应该比.parents().

jQuery Docs 中.closest(),您可以找到:

.closest()

  • 从当前元素开始
  • 向上移动 DOM 树,直到找到匹配的选择器
  • 返回的 jQuery 对象包含零个或一个元素

。父母()

  • 从父元素开始
  • 沿着 DOM 树向上移动到文档的根元素,将每个祖先元素添加到临时集合中;然后,如果提供了选择器,它会根据选择器过滤该集合
  • 返回的 jQuery 对象包含零个、一个或多个元素

因此,在您的情况下,.closest()这将是最合适的一个,因为您需要找到一个元素,即与您的选择器匹配的最接近的祖先。parents()将过滤所有可能的祖先元素,即使它已经找到了您需要的元素。

于 2011-06-06T14:47:42.953 回答
1

parents() 和最接近() 之间的唯一区别是最接近() 一旦找到匹配项就会停止,因此总是返回 0 或 1 个元素。parents() 将匹配 DOM 中的所有内容。

$(this).closest('.box-1').hide();
于 2011-06-06T14:45:41.760 回答
0

没那么快!closest() 可能是最好的,但并非总是如此!以下是您可以自己找出答案的方法。使用Firebug time() 和 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"); 
于 2011-07-25T22:08:21.843 回答