jQuery 中 :hidden 和 :not(:visible) 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17425543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 19:02:26  来源:igfitidea点击:

Difference between :hidden and :not(:visible) in jQuery

jqueryjquery-selectors

提问by Meryovi

I know that both jQuery selectors match elements that are not visible (widthor heightequal to 0, display: none, parent with display: none), and I believe it is implied they should yield the same result in thedocs.

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

For readability reasons, I would rather use :hiddenbut I want to know:

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

  • Are there any potential pitfalls that I should consider?
  • Will I always get the exact same result?
  • Which option has better performance?
  • 我应该考虑任何潜在的陷阱吗?
  • 我总是会得到完全相同的结果吗?
  • 哪个选项具有更好的性能?

回答by Mark Schultheiss

  • EDIT 3/22/2016: add to answer re: jQuery 1.12/2.2 and 3.0(*see end of answer)
  • EDIT 3/8/2016: enhance answer
  • 编辑 3/22/2016:添加回答:jQuery 1.12/2.2 和 3.0(*见答案结尾)
  • 编辑 3/8/2016:增强答案


Elements can be considered hidden for several reasons:

元素可以被认为是隐藏的,原因有几个:

  • They have a CSS displayvalue of none.
  • They are form elements with type="hidden".
  • Their width and height are explicitly set to 0.
  • An ancestor element is hidden, so the element is not shown on the page.
  • 它们的 CSSdisplay值为none.
  • 它们是带有 的表单元素type="hidden"
  • 它们的宽度和高度明确设置为 0。
  • 祖先元素被隐藏,因此该元素不会显示在页面上。

Elements with visibility: hiddenor opacity: 0are considered to be visible, since they still consume space in the layout. During animations that hide an element, the element is considered to be visible until the end of the animation.

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

Elements that are not in a document are not considered to be visible; jQuery does not have a way to know if they will be visible when appended to a document since it depends on the applicable styles.

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

The :hiddenselector is the opposite of the :visibleselector. So, every element selected by :hiddenisn't selected by :visibleand vice versa.

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

During animations to show an element, the element is considered to be visible at the start of the animation.

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

How :hiddenis determined was changed in jQuery 1.3.2. An element is assumed to be hidden if it or any of its parents consumes no space in the document. CSS visibility isn't taken into account

如何:hidden确定在 jQuery 1.3.2 中发生了变化。如果一个元素或其任何父元素不占用文档中的空间,则假定该元素是隐藏不考虑 CSS 可见性



Clarification"width or height equal to 0," - not strictly true as some browsers (opera) reports less than 0 in some instances so jQuery uses <=0internally.

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

  1. Are there any potential pitfalls that I should consider?
  2. Will I always get the exact same result?
  3. Which option has better performance?
  1. 我应该考虑任何潜在的陷阱吗?
  2. 我总是会得到完全相同的结果吗?
  3. 哪个选项具有更好的性能?

1: "Pitfalls" other than obvious of which I am unaware of any, is somewhat subjective. I say this as I try to avoid "negative" tests in code (not x or !x type checks) as equality checks are more intuitive for my brain to understand.

1:除了明显的我不知道的“陷阱”之外,还有一些主观性。我这么说是因为我试图避免代码中的“否定”测试(不是 x 或 !x 类型检查),因为相等性检查对我的大脑来说更直观。

2: Yes, the result should be the same

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

3: Re: Performance Difference between: RE: 1.10.1 version

3:Re:性能区别:RE:1.10.1 版本

Visible condition check uses the not hidden internally:

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

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

So it could be said that strictly speaking "hidden" should be more efficient avoiding the "not" condition.

所以可以说严格来说“隐藏”应该更有效地避免“非”条件。

Internally, jQuery uses a "right to left" selector so the selector will make more of difference in some cases.

在内部,jQuery 使用“从右到左”选择器,因此选择器在某些情况下会产生更大的差异。

For performance, use

为了性能,请使用

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

or

或者

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

rather than either

而不是

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

or

或者

$('selector:hidden')

Why is this? :hiddenis a jQuery extension and therefore cannot take advantage of the performance boost provided by the native DOM querySelectorAll()method. (see the right to left parsing of the Sizzle engine for how it will occur)

为什么是这样?:hidden是 jQuery 扩展,因此无法利用原生 DOMquerySelectorAll()方法提供的性能提升。(请参阅 Sizzle 引擎的从右到左解析,了解它是如何发生的)

Forms/format of the selector

选择器的形式/格式

This is because for the $('selector:hidden')form, it will select (walking the DOM)

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

  1. all hidden elements first,
  2. then select those matching the selector from that set. It would be preferred to match the selector first, then filter those in that set that are hidden.
  1. 首先是所有隐藏元素,
  2. 然后从该集合中选择与选择器匹配的那些。最好先匹配选择器,然后过滤该集中隐藏的选择器

internal "isHidden" function: (jQuery 1.10.1)

内部“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 );
}

Used for example in the .showHideinternally such as:

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

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

Worth noting that the "hidden" attribute in defaultPrefilteris:

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

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

Special note on style:

款式特别说明:

Setting an elements CSS as:

将元素 CSS 设置为:

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

is very fast.

非常快。

You can also detect this very fast:

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

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

Remember though that the element still takes up space whereas document.getElementById("hide-me").style.display = "block";does seem to make it visible but keep in mind that some PARENT might NOT be visiblethus the element might still be considered "hidden" - and jQuery does detect this (see above)

请记住,尽管该元素仍然占用空间,而document.getElementById("hide-me").style.display = "block";似乎确实使它可见,但请记住,某些PARENT 可能不可见,因此该元素可能仍被认为是“隐藏的” - jQuery 确实检测到了这一点(见上文)

Additional reference: https://api.jquery.com/hidden-selector/

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

Additional information re: jQuery 1.12/2.2 and 3.0 3/22/2016 edit

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

There have been some significant speed improvements in these versions.

这些版本在速度上有一些显着的改进。

This change can yield up to 1600% speed improvementswow! By taking advantage of caching when possible - which from what I have observed often occurs with these selectors. Test your pages with both if you have need for improvement or concerns in this area and use cases if heavily utilized within your pages.

这个改变可以产生高达1600% 的速度提升哇!通过在可能的情况下利用缓存 - 从我观察到的这些选择器经常发生。如果您在这方面需要改进或存在顾虑,请同时测试您的页面,如果在您的页面中大量使用,则使用用例测试您的页面。

You should see improved performance with .show()and .hide()as a result.

因此,您应该会看到使用.show()和改进的性能.hide()

jQuery 1.12+ and 2.2.0+ and 3.0 modify the meaning of the :visibleand :hiddenfilters. Elements will be considered :visibleif they have layout boxes. This includes those with zero width and/or height. For your selectors beware of the count. Examples: inline elements with no content and brelements will now be selected by the :visiblefilter.

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

Page Markup examples:

页面标记示例:

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

With the following sector:

具有以下部门:

var visibleElementCount = $('body').find(':visible').length;
  • In jQuery 1.11.1 and 2.1.4 return value 2 for visibleElementCount
  • In jQuery 1.12+ and 2.2.0+ and 3.0 you'll obtain 4 for visibleElementCount. Test when you rely upon this fact as it may be a breaking change for your pages.
  • 在 jQuery 1.11.1 和 2.1.4 中返回值 2 visibleElementCount
  • 在 jQuery 1.12+ 和 2.2.0+ 和 3.0 中,您将获得 4 for visibleElementCount. 测试您何时依赖此事实,因为它可能对您的页面造成重大更改。

回答by Neeraj Singh

Hmm.. interesting :)

嗯..有趣:)

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

Now some other facts:

现在还有一些其他的事实:

css selector 'visibility: hidden;' = 'opacity: 0;' = not displayin page but occupy space.

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

css selector 'display: none;' = not showing in pageand also not occupying space.

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

by jQuery you can play with element who have 'display: none'style

通过 jQuery,您可以使用具有'display: none'样式的元素

HTML Example:

HTML 示例:

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

CSS Example:

CSS 示例:

.display{
  display: none;
}

Check:

查看:

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

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

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

回答by Undefined

They both will act in the same way with no conceivable difference.

他们都将以相同的方式行事,没有想象中的区别。

Both will get you elements that take up space on the page. This includes elements with the visibility: hiddenproperty.

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

jsfiddle showing this in action.

jsfiddle 展示了这一点。