【问题标题】:Which is more efficient: .parent().parent().parent() ~or~ parents(".foo") ~or~ closest(".foo")哪个更有效: .parent().parent().parent() ~or~ parents(".foo") ~or~most(".foo")
【发布时间】:2011-01-16 22:07:53
【问题描述】:

我有一个 A 标记,它触发了它的伟大-伟大-伟大-祖父母的动画。以下所有方法都可以,但哪种方法最有效,为什么?

$(this).parent().parent().parent().parent().parent().animate(...);

$(this).parents(".foo").animate(...);

$(this).closest(".foo").animate(...);

我怀疑第一个可能是,因为它是最明确的,但出于维护原因(嵌套可能会改变)我更喜欢第二个。他们都看起来在实践中运行顺利。

【问题讨论】:

  • 我想你在那里回答了你自己的问题。如果它足够平滑,如果可维护性会受到如此严重的影响,请不要进行微优化。 :)

标签: jquery jquery-selectors


【解决方案1】:

这是一个分析:

  • parent() 在 DOM 树中仅向上移动一层。
  • parents(".foo") 走到根并只选择那些与给定选择器 .foo 匹配的元素。
  • closest(".foo") 走到根,但一旦元素与选择器 .foo 匹配就停止。

所以我会选择最后一个,closest(".foo")。原因:

  • 这比链接parent 更好,因为如果您的文档因删除或添加一个层次结构而发生更改,则无需更改 jQuery 代码。
  • 比parents(".foo") 更好,因为它会在找到匹配项后立即停止。

【讨论】:

    【解决方案2】:

    仅当您在“点击”元素上上升或处于同一级别时,最接近才有用。

    例如,如果您必须遵循以下场景:

    <div class="controls radio-other">
        <label class="radio"><input type="radio" name="item">Option one</label>
        <label class="radio"><input type="radio" name="item">Option two</label>
        <label class="radio"><input type="radio" name="item" class="other-option" data-othertarget="#otherone"> Other... </label>
        <input type="text" placeholder="Alternative answer" id="otherone" class="hidden">
    </div>
    

    那么closest('#otherone') 将找不到$('.other-option').click() 上的隐藏文本字段 在这种情况下,更好的解决方案是使用$(this).parentsUntil('.radio-other').find('#otherone')

    看着我的回答,我在这里做了一个jsperf,它反映了上述不同解决方案的场景。只需使用对您的 html 场景最有用的内容。 结果是parent().parent() 是最快的方法,但是如果您的 html 使用更灵活,这并不总是一个好的选择。添加一个 div 父级和 parent().parent() 中断。

    【讨论】:

      【解决方案3】:

      您进行了性能测量是一件非常好的事情。这正是在这种情况下应该做的。如果在实践中一切看起来运行顺利并且您对性能感到满意,请选择最易读的一个(第二和第三看起来还可以)。

      【讨论】:

        【解决方案4】:

        我想我看到了 John Resig 的介绍,他说最接近的() 更加优化,这很有意义。 Closest() 是 jQuery 的一个较新的补充,它正好解决了这个丑陋的 parent().parent() 链。另一方面, parents() 返回一个与您的 foo 类匹配的父数组,并且与找到第一个元素并停止搜索的最接近的 () 相比,在搜索方面更加贪婪。

        如果您正在寻找最接近的匹配项,我敢打赌,最接近的() 是最有效的。

        【讨论】:

          【解决方案5】:

          我无法评论实际速度,但是第一个将您与特定的元素层次结构联系起来,我会回避。

          就我个人而言,无论如何我都会尽量少用类选择器。我意识到通常没有其他方法,但如果我可以考虑 ID 选择器,那么我知道性能可能会有所提高。

          【讨论】:

            【解决方案6】:

            您也可以使用parents('.foo:first')。我猜和closest()差不多。

            【讨论】:

              【解决方案7】:

              在 Firefox 3.6.3 中的快速测试表明 parents('.foo').eq(0) 实际上比 closest('.foo') 快得多。它是否可维护尚有争议,但在特定情况下它可能会被证明更“有效”。

              【讨论】:

              • 如果你只追求速度,你根本不应该使用 jQuery 外观,而只是简单的 DOM 遍历:$(this.parentNode.parentNode.parentNode.parentNode.parentNode).animate(…)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-02-11
              • 1970-01-01
              • 1970-01-01
              • 2014-04-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多