Ответ 1
- РЕДАКТИРОВАТЬ 3/22/2016: добавить ответ re: 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," - не строго верно, поскольку некоторые браузеры (опера) сообщают меньше 0 в некоторых случаях, поэтому jQuery использует <=0
внутренне.
- Есть ли какие-либо потенциальные проблемы, которые я должен рассмотреть?
- Всегда ли получаю тот же результат?
- Какой вариант имеет лучшую производительность?
1: "Ловушки", кроме очевидных, о которых я не знаю ни одного, несколько субъективны. Я говорю об этом, пытаясь избежать "отрицательных" тестов в коде (не проверять x или! X), поскольку проверки на равенство более понятны для понимания моим мозгом.
2: Да, результат должен быть таким же
3: Re: Производительность Разница между: 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/
Дополнительная информация re: jQuery 1.12/2.2 и 3.0 3/22/2016 edit
В этих версиях произошли значительные улучшения скорости.
- Ссылка на это сообщение: 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
, если у них есть макеты. Сюда входят те, которые имеют нулевую ширину и/или высоту. Для ваших селекторов остерегайтесь подсчета. Примеры: встроенные элементы без содержимого и элементы br
теперь будут выбраны фильтром :visible
.
Примеры разметки страницы:
<div>
</div>
<span></span>
<br />
<p>
</p>
В следующем секторе:
var visibleElementCount = $('body').find(':visible').length;
- В jQuery 1.11.1 и 2.1.4 возвращаемое значение 2 для
visibleElementCount
- В jQuery 1.12+ и 2.2.0+ и 3.0 вы получите 4 для
visibleElementCount
. Проверьте, когда вы полагаетесь на этот факт, так как это может быть изменением для ваших страниц.