Как работает jQuery, когда есть несколько элементов с одним и тем же "идентификатором"?
Я получаю данные с сайта Google AdWords, который имеет несколько элементов с одним и тем же id.
не могли бы вы объяснить, почему следующие 3 запроса не приводят к одному и тому же ответу (2)?
HTML:
<div>
<span id="a">1</span>
<span id="a">2</span>
<span>3</span>
</div>
JS:
$(function() {
var w = $("div");
console.log($("#a").length); // 1 - Why?
console.log($("body #a").length); // 2
console.log($("#a", w).length); // 2
});
6 ответов:
наличие 2 элементов с одинаковым идентификатором не является допустимым html в соответствии со спецификацией W3C.
когда ваш селектор CSS имеет только селектор ID (и не используется в определенном контексте), jQuery использует собственный
document.getElementByIdметод, который возвращает только первый элемент с этим ID.однако в двух других случаях jQuery полагается на механизм селектора Sizzle (или
querySelectorAll, Если доступно), который, по-видимому, выбирает оба элемента. Результаты могут отличаться в зависимости от браузера основа.однако, вы никогда не должны иметь два элемента на одной странице с тем же идентификатором. Если вам это нужно для вашего CSS, используйте класс вместо этого.
если вы абсолютно должны выбрать по дубликату ID, используйте селектор атрибутов:
$('[id="a"]');взгляните на скрипку:http://jsfiddle.net/P2j3f/2/
Примечание: если возможно, вы должны квалифицировать этот селектор с помощью селектора тегов, например:
$('span[id="a"]');
должен быть только один элемент с заданным идентификатором. Если вы застряли в этой ситуации, см. вторую половину моего ответа для вариантов.
как браузер ведет себя, когда у вас есть несколько элементов с одинаковым идентификатором (незаконный 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"). Если селектор является более сложным, чем это и , jQuery часто передает селектор во встроенную функцию браузера, которая будет иметь реализацию, специфичную для этого браузера. ЕслиquerySelectorAll()не существует, тогда он будет использовать механизм селектора Sizzle, чтобы вручную найти селектор, который будет иметь свою собственную реализацию. Таким образом, вы можете иметь по крайней мере три разных реализации в одном семействе браузеров в зависимости от точного селектора и того, насколько новый браузер. Тогда отдельные браузеры будут иметь свои собственныеquerySelectorAll()реализации. Если вы хотите надежно справиться с этой ситуацией, вам, вероятно, придется использовать свой собственный код итерации как я показано выше.
jQuery
idселектор возвращает только один результат. Элементdescendantиmultipleселекторы во втором и третьем операторах предназначены для выбора нескольких элементов. Это похоже на:Инструкции 1
var length = document.getElementById('a').length;...Дает один результат.
заявление 2
var length = 0; for (i=0; i<document.body.childNodes.length; i++) { if (document.body.childNodes.item(i).id == 'a') { length++; } }...Дает два результата.
утверждение 3
var length = document.getElementById('a').length + document.getElementsByTagName('div').length;...Также дает два результата.
каждое значение идентификатора должно использоваться только один раз в документе. Если одному и тому же идентификатору присвоено несколько элементов, запросы, использующие этот идентификатор, будут выбирать только первый сопоставленный элемент в DOM. Однако на это поведение не следует полагаться; документ с несколькими элементами, использующими один и тот же идентификатор, недопустим.
Непослушный Google. Но они даже не закрывают свои
<html>и<body>теги I слышать. Вопрос в том, почему 2-й и 3-й запросы Миши возвращают 2, а не 1.
Если у вас есть несколько элементов с одинаковым идентификатором или одинаковым именем, просто назначьте один и тот же класс этим нескольким элементам и получите к ним доступ по индексу и выполните необходимую операцию.
<div> <span id="a" class="demo">1</span> <span id="a" class="demo">2</span> <span>3</span> </div>JQ:
$($(".demo")[0]).val("First span"); $($(".demo")[1]).val("Second span");
вы можете просто написать $('span#a').длина, чтобы получить длину.
вот решение для вашего кода:
console.log($('span#a').length);попробуйте JSfiddle: https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/
Comments