区别:隐藏和:不是(:可见)在jQuery中

时间:2013-07-02 12:23:12

标签: jquery jquery-selectors

我知道两个jQuery选择器都匹配不可见的元素(widthheight等于0,display: none,父display: none),我相信它暗示他们应该在the docs中产生相同的结果。

出于可读性原因,我宁愿使用:hidden,但我想知道:

  • 我是否应该考虑任何潜在的陷阱?
  • 我会得到完全相同的结果吗?
  • 哪个选项有更好的表现?

3 个答案:

答案 0 :(得分:47)

  • 编辑2016年3月22日:添加回答:jQuery 1.12 / 2.2和3.0 (*请参阅回答结束)
  • 编辑3/8/2016:增强答案

由于以下几个原因,可以将元素视为隐藏:

  • 他们的CSS display值为none
  • 它们是type="hidden"的表单元素。
  • 它们的宽度和高度明确设置为0.
  • 隐藏了一个祖先元素,因此页面上不会显示该元素。

visibility: hiddenopacity: 0的元素被认为是可见的,因为它们仍占用了布局中的空间。在隐藏元素的动画期间,该元素在动画结束之前被视为可见

不认为文档中没有的元素是可见的; jQuery没有办法知道它们在附加到文档时是否可见,因为它取决于适用的样式。

:hidden选择器与:visible选择器相反。因此,:hidden选择的每个元素都不会被:visible选中,反之亦然。

在显示元素的动画期间,该元素在动画开始时被视为可见

如何确定:hidden在jQuery 1.3.2中已更改。如果元素或其任何父元素在文档中不占用空间,则假定元素隐藏未考虑CSS可见性


澄清&#34;宽度或高度等于0,&#34; - 严格来说并非如此,因为某些浏览器(opera)在某些情况下报告小于0,因此jQuery在内部使用<=0

  1. 我是否应该考虑任何潜在的陷阱?
  2. 我会得到完全相同的结果吗?
  3. 哪个选项有更好的表现?
  4. 1:&#34;陷阱&#34;除了我不知道的任何明显的,有点主观。我说这是因为我试图避免&#34;否定&#34;代码中的测试(不是x或!x类型检查)作为等式检查更直观,让我的大脑能够理解。

    2:是的,结果应该是相同的

    3:Re:表现 区别:RE:1.10.1版本

    可见条件检查使用内部未隐藏:

    jQuery.expr.filters.visible = function( elem ) {
        return !jQuery.expr.filters.hidden( elem );
    };
    

    所以可以说严格来说&#34;隐藏&#34;应该更有效率避免&#34;不是&#34;条件。

    在内部,jQuery使用&#34;从右到左&#34;选择器使选择器在某些情况下会产生更大的差异。

    要获得表现,请使用

    $(selector).filter(':hidden')
    

    $(selector).not(':visible') 
    

    而不是

    $('selector:not(:visible)') 
    

    $('selector:hidden')
    

    这是为什么? :hidden是jQuery扩展,因此无法利用本机DOM querySelectorAll()方法提供的性能提升。 (参见Sizzle引擎从右到左解析它将如何发生)

    选择器的表单/格式

    这是因为对于$('selector:hidden')表格,它会选择(走DOM)

    1. 首先是所有隐藏的元素,
    2. 然后选择与该集合中的选择器匹配的那些。首选首先匹配选择器,然后过滤隐藏的那些内容。
    3. 内部&#34;隐藏&#34;功能:(jQuery 1.10.1)

      function isHidden( elem, el ) {
          // isHidden might be called from jQuery#filter function;
          // in that case, element will be second argument
          elem = el || elem;
          return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
      }
      

      例如在.showHide内部使用,例如:

      if ( elem.style.display === "" && isHidden( elem ) ) {
      

      值得注意的是&#34;隐藏&#34; defaultPrefilter中的属性是:

      hidden = elem.nodeType && isHidden( elem ),
      

      style 的特别说明:

      将CSS元素设置为:

      document.getElementById("hide-me").style.visibility = "hidden";
      

      非常快。

      您也可以非常快速地检测到这一点:

      document.getElementById("hide-me").style.visibility  === "hidden";
      

      请记住,虽然该元素仍然占用空间,而document.getElementById("hide-me").style.display = "block";似乎确实使其可见,但请记住,某些 PARENT可能不可见因此该元素可能仍会被视为& #34;隐藏&#34; - 并且jQuery确实检测到了这一点(见上文)

      其他参考:https://api.jquery.com/hidden-selector/

      补充信息:jQuery 1.12 / 2.2和3.0 3/22/2016编辑

      这些版本的速度有了显着提升。

      此更改可以提高 1600%的速度提升哇!通过在可能的情况下利用缓存 - 从我观察到的这些选择器经常发生。如果您需要改进或关注此区域,请使用两者测试您的页面;如果您的页面中使用频率很高,则使用案例。

      您应该会看到.show().hide()的效果得到改善。

      jQuery 1.12+和2.2.0+和3.0修改了:visible:hidden过滤器的含义。如果元素具有布局框,则会将其视为:visible。这包括宽度和/或高度为零的那些。对于您的选择器,请注意计数。示例:br过滤器现在将选择没有内容和:visible元素的内联元素。

      页面标记示例:

      <div>
      </div>
      <span></span>
      <br />
      <p>
      </p>
      

      以下部门:

      var visibleElementCount = $('body').find(':visible').length;
      
      • 在jQuery 1.11.1和2.1.4中,为visibleElementCount
      • 返回值2
      • 在jQuery 1.12+和2.2.0+和3.0中,您将获得visibleElementCount的4。当你依赖这个事实时进行测试,因为这可能是你网页的重大变化。

答案 1 :(得分:5)

嗯......有趣:)

:hidden = :not(:visible) = css selector 'display: none;'

现在还有其他一些事实:

页面中的css选择器'visibility: hidden;' = 'opacity: 0;' = not display,但occupy space

css选择器'display: none;' = not showing in page以及not occupying space

通过jQuery,您可以使用'display: none'样式

的元素

HTML示例:

<input type='text' class='display' value='Display' />

CSS示例:

.display{
  display: none;
}

检查:

alert($('.display').val());// Display

$('.display').val('Hello');

alert($('.display').val());// Hello

答案 2 :(得分:3)

他们都会以同样的方式行事,没有任何可想象的差异。

两者都会为您提供占用页面空间的元素。这包括具有visibility: hidden属性的元素。

jsfiddle showing this in action.