Мне действительно нужно проверить, существует ли элемент с jQuery?
недавно у меня был вопрос о том, как правильно проверить, существует ли элемент с jQuery. Я нашел ответ здесь:
https://learn.jquery.com/using-jquery-core/faq/how-do-i-test-whether-an-element-exists/
в итоге:
if ( $( "#myDiv" ).length ) {
// Do something
}
один парень, с которым я работаю, говорит, что правильный способ проверки должен быть:
if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
// Do something
}
имеет ли это значение? Я имею в виду с точки зрения производительности или задержки, выполняют ли они же?
также:
$( "#myDiv" ).show();
$( "#myDiv" ).hide();
$( "#myDiv" ).val('');
в этих типах функций jQuery, кажется, нет if
проверка необходима, потому что они не вызывают ошибку, если #myDiv
не существует, верно?
для чего это стоит, я использую jQuery 1.6.4.
5 ответов:
один парень, с которым я работаю, говорит, что правильный способ проверки должен быть:
if ($( "#myDiv" ) && $( "#myDiv" ).length ) { //do something }
он ошибается, по крайней мере в плане
$( "#myDiv" ) &&
часть. в jQuery$(selector)
всегда возвращает объект, который по определению-истина. Так что эта часть бессмысленна, и повторный запрос DOM без причины.я имею в виду от исполнения или задержки мудрые, они выполняют то же самое?
повторный запрос DOM без причины это пустая трата времени, но в большинстве случаев это не имеет значения каким-либо заметным образом, и особенно не для селекторов ID, таких как
$("#myDiv")
которые оптимизированы jQuery в вызовыgetElementById
(что невероятно быстро). Так что, с одной стороны, да, это расточительная дополнительная работа. С другой стороны, браузеры настолько быстры в эти дни, что у вас, вероятно, есть большая рыба, чтобы жарить. Но это, вероятно, дополнительный бессмысленный код, который является более серьезной проблемой.к общей точке: jQuery is set-based. Это означает, что операции над наборами без элементов в них не являются операторами. Например:
$(".foo").addClass("bar");
...является no-op (не ошибка), если нет
.foo
элементы находятся в DOM.проверить
length
если и когда вы заботитесь ли вы соответствовали элементы. Если вы не заботитесь и просто хотите выполнять операции на них если они есть, просто идти вперед и делать операцию (с одной важной оговоркой1).так что в основном, есть три сценарии:
вы знаете, что элементы будут там, поэтому проверка бессмысленна
=> проверкавы не знаете, что элементы будут там, но вы не заботитесь и просто хотите работать на них если они там
=> проверкавы заботитесь, есть ли элементы по какой-то другой причине
=> сделать проверьте
1 вот важная оговорка: если вы вызываете функцию jQuery, которая возвращает что-то другое, чем объект jQuery (например,
val()
илиoffset()
илиposition()
и т. д.), когда вы вызываете его на пустой набор, он обычно возвращаетundefined
(за исключениемtext()
, что вернет""
[text()
не похож на других в нескольких отношениях; это один из них]). Так что написание кода, который наивно предполагает эти вещи вернет то, что вы ожидаете, даже когда набор пуст, укусит вас.например:
if ($(".foo").offset().top > 20)
...выдаст ошибку, если нет
.foo
элементы, потому чтоoffset()
вернутсяundefined
, а не объект.но это прекрасно:
$(".foo").closest(".bar").toggleClass("baz"):
...потому что даже если их нет
.foo
,closest()
вернется еще один пустой набор jQuery и вызовtoggleClass()
на нем нет.поэтому при работе с метод доступа, который не возвращает объект jQuery, если вы не знаете наверняка, что имеете дело с набором, содержащим хотя бы один элемент, вам нужно больше защиты, например:
var offset = $(".foo").offset(); if (offset && offset.top > 20)
опять же, большинство методов доступа (которые не возвращают объекты jQuery) делают это, включая
val()
,offset()
,position()
,css()
, ...
это имеет значение, и
$( "#myDiv" ).length
лучше, потому что он не работаетdocument.getElementById('myDiv')
два раза. Если бы вы кэшировали селектор, это имело бы гораздо меньшее значение:var $myDiv = $( "#myDiv" ); if ($myDiv && $myDiv.length) { ... }
однако селекторы jQuery всегда возвращают что-то это будет истолковано как "правдивость", так что
if ($('#myDiv')) {
это бессмысленная проверка.
один парень, с которым я работаю, говорит, что правильный способ проверки должен быть:
if ($( "#myDiv" ) && $( "#myDiv" ).length ) { //do something }
это утверждение ложно. Проверка
$( "#myDiv" ).length
просто вернет0
если он не найден. Чтобы быть уверенным, вот пример кода, какid
нашел, а второйid
вот нет:console.log("Count of #myDiv's found: " + $("#myDiv").length); console.log("Count of #AnotherMyDiv's found: " + $("#AnotherMyDiv").length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> <div id="myDiv"></div>
зависит от того, что вы делаете после оператора if.
подумайте об этом. Любой вызов селектора jquery возвращает объект jquery, который в основном является массивом, расширенным с помощью множества различных методов. Когда вы называете что-то вроде
$(".my-elements").show()
он будет перебирать все элементы$(".my-elements")
вернулся и применить.show()
к ним затем верните тот же объект jquery, который является цепочкой jquery.если вы просто делаете цепные вещи, то нет, вам не нужно делать если проверят. Потому что все последующие методы будут просто делать петлю, эквивалентной
for (var i=0; i<0; i++){ }
что означает, что ничего не произойдет. Если у вас есть большая цепочка, и вы запускаете ее в большом цикле, который должен быть очень производительным, вы можете сделать проверку if, но обычно это не имеет значения с точки зрения производительности.Если, однако, вы делаете что-то, что вызовет ошибку или даст вам плохой результат, если элемент не существует, то да, используйте проверку if. Например
function addHeight() { var height1 = $("#div1").height(), height2 = $("#div2").height(); $("#otherDiv").css({ top: height1 + height2 }); }
если
div1
илиdiv2
нетotherDiv
получит его верхний набор вNaN
который, вероятно, не то, что вы собираетесь. В этом случае вы хотели бы проверить, что обаdiv1
иdiv2
на самом деле существуют, но вам все равно не нужно проверятьotherDiv
потому что если он не существует ничего не произойдет в любом случае.