在jQuery中隐藏和:not(:visible)之间的区别

我知道两个jQuery选择器匹配不可见的元素( widthheight等于0, display: none ,父母display: none ),我相信这意味着它们应该在文档中产生相同的结果。

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

  • 我应该考虑哪些潜在的缺陷?
  • 我会一直得到完全相同的结果吗?
  • 哪个选项具有更好的性能?

  • 编辑3/22/2016:添加到答案重新:jQuery 1.12 / 2.2和3.0 (*见答案的结尾)
  • 编辑3/8/2016:增强答案

  • 元素可以被视为隐藏的原因有几个:

  • 他们的CSS display值为none
  • 它们是type="hidden"表单元素。
  • 它们的宽度和高度显式设置为0。
  • 祖先元素是隐藏的,所以元素不会显示在页面上。
  • 具有visibility: hidden元素visibility: hiddenopacity: 0被认为是可见的,因为它们仍然占用布局中的空间。 在隐藏元素的动画期间,元素被视为可见,直到动画结束。

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

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

    在动画中显示元素时,该元素被视为在动画开始时可见。

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


    澄清 “宽度或高度等于0” - 不严格,因为在某些情况下某些浏览器(opera)报告小于0,所以jQuery在内部使用<=0

  • 我应该考虑哪些潜在的缺陷?
  • 我会一直得到完全相同的结果吗?
  • 哪个选项具有更好的性能?
  • 1:除了我没有意识到的其他明显情况外,“陷阱”有些主观。 我这样说是因为我试图避免代码中的“负面”测试(不是x或!x类型检查),因为平等检查对我的大脑来说更直观。

    2:是的,结果应该是一样的

    3:回复:性能差异:RE:1.10.1版本

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

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

    所以可以说,严格来说“隐藏”应该更有效,避免“不”的情况。

    在内部,jQuery使用“从右到左”选择器,因此选择器在某些情况下会有更多不同。

    为了表现,请使用

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

    要么

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

    而不是两者

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

    要么

    $('selector:hidden')
    

    为什么是这样? :hidden是一个jQuery扩展,因此无法利用本机DOM querySelectorAll()方法提供的性能提升。 (请参阅Sizzle引擎从右到左的解析方式)

    选择器的表格/格式

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

  • 所有隐藏的元素首先,
  • 然后选择那些与该组中的选择器匹配的选项。 最好首先匹配选择器 ,然后过滤那些隐藏的选择器
  • 内部的“isHidden”函数:(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 ) ) {
    

    值得注意的是, defaultPrefilter中的“隐藏”属性是:

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

    款式特别注意事项:

    将元素CSS设置为:

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

    速度非常快。

    您还可以快速检测到这一点:

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

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

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

    附加信息:jQuery 1.12 / 2.2和3.0 2016/3/22编辑

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

  • 引用这篇文章:https://github.com/jquery/jquery/issues/2042
  • 相关参考:https://github.com/jquery/sizzle/issues/315#issuecomment-74336936
  • 这个改变可以产生高达1600%的速度提升哇! 尽可能利用缓存 - 从我观察到的情况来看,这些选择器经常发生。 如果您需要改进或关注此区域,请使用两种方式测试您的网页,如果在网页中大量使用它们,请使用这两种方法。

    您应该看到更好的性能.show().hide()的结果。

    jQuery 1.12+和2.2.0+和3.0修改了:visible:hidden过滤器的含义。 将考虑元素:visible如果他们有布局框,则: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中,您将获得4个visibleElementCount 。 测试当你依赖这个事实,因为它可能是你的网页的重大改变。

  • 嗯..有趣:)

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

    现在一些其他的事实:

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

    css选择器'display: none;' = not showing in page '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
    

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

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

    jsfiddle在行动中显示了这一点。

    链接地址: http://www.djcxy.com/p/263.html

    上一篇: Difference between :hidden and :not(:visible) in jQuery

    下一篇: a stack vs the stack and a heap vs the heap