Разница в jquery-селекторе $ ('# names') и $ ('input # names') - PullRequest
1 голос
/ 05 ноября 2011

У меня в html объявлен флажок:

<input id="names" name="names" type="checkbox" value="1">One</input>
<input id="names" name="names" type="checkbox" value="2">One</input>
<input id="names" name="names" type="checkbox" value="3">One</input>

Я думал, $('#names') даст мне дескриптор для всех элементов флажка, но это не так, однако $('input#names') делает.

$('#names').length is 1.

и

$('input#names').length is 3

В чем разница?jsfiddle: http://jsfiddle.net/Urbw5/8/

Спасибо, Крис.

Ответы [ 8 ]

4 голосов
/ 05 ноября 2011

Одна из причин в том, что это недействительный HTML. Элементы id должны быть уникальными. Поэтому меня не удивляет, что jQuery дает вам странные результаты. Если вам нужны все флажки «names», вы, вероятно, хотите:

$("input[name='names']")
3 голосов
/ 05 ноября 2011

$('#names') заставляет jquery использовать getElementById, который, очевидно, возвращает один элемент, тогда как $('input#names') будет делать что-то вроде: getElementsByTagName, а затем при помощи цикла находить только те, которые имеют идентификатор как names

3 голосов
/ 05 ноября 2011

Разница несущественна, id значения должны быть уникальными в документе . Если вам нужно сгруппировать входы, вам придется использовать что-то отличное от id (class часто [over] используется для этого, но вы можете сделать это также и структурно - например, все input элементы внутри данного контейнера).

Причина различий в результатах, которые вы видите, заключается в том, как оптимизирует механизм выбора jQuery (Sizzle). Если вы передадите простой селектор на основе идентификатора, Sizzle использует document.getElementById (а затем проверяет, что он получил действительно id из-за ошибок в IE до IE8). Таким образом, он возвращает один элемент.

Но если вы передаете составной селектор, такой как input#names, он не следует этому пути оптимизации и фактически выполняет поиск DOM (либо непосредственно в своем собственном коде, либо через document.querySelectorAll, если браузер его поддерживает). Обычно это включает в себя поиск всех соответствующих элементов (например, всех элементов input), а затем фильтрацию списка в соответствии с другими классификаторами. Так что бывает, что в вашем тестовом браузере Sizzle или механизм выбора браузера не закорачивают этот переключатель, даже если он должен знать, что, найдя один соответствующий элемент, это все, что ему нужно сделать.

2 голосов
/ 05 ноября 2011

Проблема в том, что ваш HTML неверен.id значения должны быть уникальными в документе.Правильный способ добиться этого - использовать class вместо:

<input class="names" name="names" type="checkbox" value="1">
<input class="names" name="names" type="checkbox" value="2">
<input class="names" name="names" type="checkbox" value="3">

и использовать jQuery:

$(".names");

В качестве альтернативы вы можете использовать селектор атрибутов, чтобы выбрать по имени:

$("input[name='names']");
2 голосов
/ 05 ноября 2011

Это несоответствие возникает из-за того, что вы используете несколько идентификаторов.

И идентификатор по определению уникален.В данном документе должен быть ровно один из любых идентификаторов.Вы не должны помещать много элементов с одинаковым идентификатором.Для этого есть имя класса.

Кроме того, отметим, что элемент <input> не должен содержать ничего (даже текстовых узлов).

<input class="names" name="names" type="checkbox" value="1">
<input class="names" name="names" type="checkbox" value="2">
<input class="names" name="names" type="checkbox" value="3">

, а затем $('.names').length = 3и $('input.names').length = 3.

2 голосов
/ 05 ноября 2011

input#names выполняет поиск элемента ввода с идентификатором names.
#names ищет любой элемент с идентификатором names.
Но так как вы не можете использовать один и тот же идентификатор для нескольких элементов на странице, это будет проблемой. Если вам нужно более одного раза на странице, используйте классы.
http://jsfiddle.net/FrxN8/

1 голос
/ 05 ноября 2011

Джеймс прав, для проверки HTML нужно использовать только один «идентификатор» только один раз.Я предполагаю, что jQuery реализован так, чтобы останавливаться при первом обнаружении идентификатора.

С другой стороны, вы ищете «входные» теги, чтобы jQuery знал, что он может найти много тегов.Но это все равно не должно работать.

Вместо этого используйте ".names", и вы получите одинаковый результат для каждого теста.

РЕДАКТИРОВАТЬ: Кстати,

$ (". Names") будет искать каждый тег с классом "names", тогда как $ ("input.names") будет искать только входные теги с классом "names".

Hopeэто помогает.

1 голос
/ 05 ноября 2011

Как говорит Джеймс, недопустимо иметь более одного элемента с одинаковым идентификатором.Для этого и используется атрибут name.Странно, что ваша вторая версия работает, но в jquery она должна быть просто причудой.

удалить идентификатор (если вам это не нужно, в этом случае убедитесь, что они уникальны).Затем выполните

('input[name="names"]').length

В отличие от большинства людей, я не рекомендую использовать занятия в этой ситуации.Вы просто раздутые дом с именами классов, которые вы не используете.Селектор атрибутов здесь совершенно действителен без добавления классов, которые вы не используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...