Должен быть только один элемент с заданным идентификатором. Если вы застряли в такой ситуации, посмотрите варианты ответа во второй половине моего ответа.
Как ведет себя браузер, когда у вас есть несколько элементов с одинаковым идентификатором (недопустимый HTML), спецификация не определена. Вы можете протестировать все браузеры и выяснить, как они ведут себя, но неразумно использовать эту конфигурацию или полагаться на какое-либо конкретное поведение.
Используйте классы, если хотите, чтобы несколько объектов имели одинаковый идентификатор.
<div>
<span class="a">1</span>
<span class="a">2</span>
<span>3</span>
</div>
$(function() {
var w = $("div");
console.log($(".a").length); // 2
console.log($("body .a").length); // 2
console.log($(".a", w).length); // 2
});
Если вы хотите надежно смотреть на элементы с одинаковыми идентификаторами, потому что вы не можете исправить документ, то вам придется сделать свою собственную итерацию, поскольку вы не можете полагаться ни на одну из встроенных функций DOM.
Вы можете сделать это так:
function findMultiID(id) {
var results = [];
var children = $("div").get(0).children;
for (var i = 0; i < children.length; i++) {
if (children[i].id == id) {
results.push(children[i]);
}
}
return(results);
}
Или, используя jQuery:
$("div *").filter(function() {return(this.id == "a");});
Рабочий пример jQuery: http://jsfiddle.net/jfriend00/XY2tX/.
Относительно того, почему вы получаете разные результаты, это будет связано с внутренней реализацией любого фрагмента кода, выполняющего фактическую операцию селектора. В jQuery вы можете изучить код, чтобы выяснить, что делает данная версия, но, поскольку это недопустимый HTML, нет гарантии, что он останется неизменным со временем. Из того, что я видел в jQuery, сначала проверяется, является ли селектор простым идентификатором, таким как #a
, и, если это так, просто используется document.getElementById("a")
. Если селектор более сложен, чем этот, и querySelectorAll()
существует, jQuery часто передает селектор встроенной функции браузера, которая будет иметь реализацию, специфичную для этого браузера. Если querySelectorAll()
не существует, он будет использовать механизм выбора Sizzle для ручного поиска переключателя, который будет иметь свою собственную реализацию. Таким образом, вы можете иметь как минимум три разных реализации в одном семействе браузеров, в зависимости от точного селектора и того, насколько новый браузер. Тогда отдельные браузеры будут иметь свои собственные реализации querySelectorAll()
. Если вы хотите надежно справиться с этой ситуацией, вам, вероятно, придется использовать свой собственный итерационный код, как показано выше.