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
Difference between :hidden and :not(:visible) in jQuery
提问by Meryovi
I know that both jQuery selectors match elements that are not visible (width
or height
equal to 0, display: none
, parent with display: none
), and I believe it is implied they should yield the same result in thedocs.
我知道,无论jQuery选择匹配不可见(元素width
或height
等于0, display: none
,父母一方display: none
),我认为这是暗示他们应该得到的结果相同的文档。
For readability reasons, I would rather use :hidden
but 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
display
value ofnone
. - 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.
- 它们的 CSS
display
值为none
. - 它们是带有 的表单元素
type="hidden"
。 - 它们的宽度和高度明确设置为 0。
- 祖先元素被隐藏,因此该元素不会显示在页面上。
Elements with visibility: hidden
or opacity: 0
are 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 :hidden
selector is the opposite of the :visible
selector. So, every element selected by :hidden
isn't selected by :visible
and 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 :hidden
is 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 <=0
internally.
澄清“宽度或高度等于 0”,- 并非严格正确,因为某些浏览器(opera)在某些情况下报告小于 0,因此 jQuery 在<=0
内部使用。
- Are there any potential pitfalls that I should consider?
- Will I always get the exact same result?
- Which option has better performance?
- 我应该考虑任何潜在的陷阱吗?
- 我总是会得到完全相同的结果吗?
- 哪个选项具有更好的性能?
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? :hidden
is 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)
- all hidden elements first,
- 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.
- 首先是所有隐藏元素,
- 然后从该集合中选择与选择器匹配的那些。最好先匹配选择器,然后过滤该集中隐藏的选择器。
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 .showHide
internally such as:
例如在.showHide
内部使用,例如:
if ( elem.style.display === "" && isHidden( elem ) ) {
Worth noting that the "hidden" attribute in defaultPrefilter
is:
值得注意的是,中的“隐藏”属性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.
这些版本在速度上有一些显着的改进。
- Reference this post: https://github.com/jquery/jquery/issues/2042
- Related reference: https://github.com/jquery/sizzle/issues/315#issuecomment-74336936
- 参考这篇文章:https: //github.com/jquery/jquery/issues/2042
- 相关参考:https: //github.com/jquery/sizzle/issues/315#issuecomment-74336936
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 :visible
and :hidden
filters. Elements will be considered :visible
if 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 br
elements will now be selected by the :visible
filter.
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 display
in page but occupy space
.
'visibility: hidden;' = 'opacity: 0;' = not display
页面中的css 选择器但是occupy space
.
css selector 'display: none;' = not showing in page
and also not occupying space
.
css 选择器'display: none;' = not showing in page
和not 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: hidden
property.
两者都会为您提供占用页面空间的元素。这包括具有该visibility: hidden
属性的元素。