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

Mer*_*ovi 33 jquery jquery-selectors

我知道,无论jQuery选择匹配不可见(元素widthheight等于0, display: none,父母一方display: none),我认为这是暗示他们应该得到的结果相同 文档.

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

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

Mar*_*iss 47

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

元素可被视为隐藏,原因如下:

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

元素带visibility: hidden或被opacity: 0认为是可见的,因为它们仍然占用布局中的空间.在隐藏元素的动画期间,该元素在动画结束前被视为可见.

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

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

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

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


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

  1. 我应该考虑哪些潜在的陷阱?
  2. 我会一直得到完全相同的结果吗?
  3. 哪个选项有更好的表现?

1:除了我不知道的任何明显的"陷阱"之外,有点主观.我说这是因为我试图避免代码中的"否定"测试(不是x或!x类型检查),因为相等检查对我的大脑来说更直观.

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

3:Re:性能差异:RE:1.10.1版本

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

jQuery.expr.filters.visible = function( elem ) {
    return !jQuery.expr.filters.hidden( elem );
};
Run Code Online (Sandbox Code Playgroud)

所以可以说,严格来说,"隐藏"应该更有效,避免"不"条件.

在内部,jQuery使用"从右到左"选择器,因此选择器在某些情况下会产生更多不同.

为了性能,请使用

$(selector).filter(':hidden')
Run Code Online (Sandbox Code Playgroud)

要么

$(selector).not(':visible') 
Run Code Online (Sandbox Code Playgroud)

而不是

$('selector:not(:visible)') 
Run Code Online (Sandbox Code Playgroud)

要么

$('selector:hidden')
Run Code Online (Sandbox Code Playgroud)

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

选择器的表单/格式

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

  1. 所有隐藏的元素首先,
  2. 然后选择与该集合中的选择器匹配的那些.首先匹配选择器,然后过滤那些隐藏的选择器.

内部"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 );
}
Run Code Online (Sandbox Code Playgroud)

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

if ( elem.style.display === "" && isHidden( elem ) ) {
Run Code Online (Sandbox Code Playgroud)

值得注意的是"隐藏"属性defaultPrefilter是:

hidden = elem.nodeType && isHidden( elem ),
Run Code Online (Sandbox Code Playgroud)

风格特别说明:

将CSS元素设置为:

document.getElementById("hide-me").style.visibility = "hidden";
Run Code Online (Sandbox Code Playgroud)

非常快.

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

document.getElementById("hide-me").style.visibility  === "hidden";
Run Code Online (Sandbox Code Playgroud)

请记住,该元素仍然占用空间,document.getElementById("hide-me").style.display = "block";但似乎确实使其可见,但请记住,某些PARENT可能不可见,因此该元素可能仍被视为"隐藏" - 并且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>
Run Code Online (Sandbox Code Playgroud)

有以下部门:

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


Nee*_*ngh 5

嗯..有趣:)

:hidden = :not(:visible) = css selector 'display: none;'
Run Code Online (Sandbox Code Playgroud)

现在其他一些事实:

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

css选择器'display: none;' = not showing in pagenot occupying space.

通过jQuery,你可以玩有'display: none'风格的元素

HTML示例:

<input type='text' class='display' value='Display' />
Run Code Online (Sandbox Code Playgroud)

CSS示例:

.display{
  display: none;
}
Run Code Online (Sandbox Code Playgroud)

校验:

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

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

alert($('.display').val());// Hello
Run Code Online (Sandbox Code Playgroud)