Como o jQuery funciona quando existem vários elementos com o mesmo “id”?

Eu busco dados do site do Google AdWords que tem vários elementos com o mesmo id .

Você poderia, por favor, explicar por que as seguintes 3 perguntas não resultam com a mesma resposta (2)?

Demonstração ao vivo

HTML:

 
1 2 3

JS:

 $(function() { var w = $("div"); console.log($("#a").length); // 1 - Why? console.log($("body #a").length); // 2 console.log($("#a", w).length); // 2 }); 

   

Ter 2 elementos com o mesmo ID não é válido, de acordo com a especificação W3C.

Quando seu seletor CSS tem apenas um seletor de ID (e não é usado em um contexto específico), o jQuery usa o método nativo document.getElementById , que retorna apenas o primeiro elemento com esse ID.

No entanto, nas outras duas instâncias, o jQuery depende do mecanismo seletor Sizzle (ou querySelectorAll , se disponível), que aparentemente seleciona os dois elementos. Os resultados podem variar por navegador.

No entanto, você nunca deve ter dois elementos na mesma página com o mesmo ID. Se você precisar dele para o seu CSS, use uma class.


Se você realmente precisa selecionar por ID duplicada, use um seletor de atributos:

 $('[id="a"]'); 

Dê uma olhada no violino: http://jsfiddle.net/P2j3f/2/

Nota: se possível, você deve qualificar esse seletor com um seletor de tags, assim:

 $('span[id="a"]'); 

Deve haver apenas um elemento com um determinado ID. Se você está preso a essa situação, veja a segunda metade da minha resposta para opções.

Como um navegador se comporta quando você tem vários elementos com o mesmo id (HTML ilegal) não é definido pela especificação. Você pode testar todos os navegadores e descobrir como eles se comportam, mas é insensato usar essa configuração ou confiar em qualquer comportamento específico.

Use classs se você quiser que vários objects tenham o mesmo identificador.

 
1 2 3
$(function() { var w = $("div"); console.log($(".a").length); // 2 console.log($("body .a").length); // 2 console.log($(".a", w).length); // 2 });

Se você quiser analisar com segurança os elementos com IDs que são os mesmos, porque não é possível corrigir o documento, será necessário fazer sua própria iteração, já que não pode confiar em nenhuma das funções internas do DOM.

Você poderia fazer assim:

 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); } 

Ou, usando jQuery:

 $("div *").filter(function() {return(this.id == "a");}); 

Exemplo de trabalho do jQuery: http://jsfiddle.net/jfriend00/XY2tX/ .

Quanto a Por que você obtém resultados diferentes, isso teria a ver com a implementação interna de qualquer parte do código que estivesse executando a operação real do seletor. No jQuery, você poderia estudar o código para descobrir o que qualquer versão estava fazendo, mas como isso é um HTML ilegal, não há garantia de que ele permanecerá o mesmo ao longo do tempo. Pelo que eu vi no jQuery, ele primeiro verifica se o seletor é um id simples como #a e, em caso afirmativo, apenas usei document.getElementById("a") . Se o seletor for mais complexo que aquele e querySelectorAll() existir, o jQuery geralmente passará o seletor para a function querySelectorAll() navegador, que terá uma implementação específica para esse navegador. Se querySelectorAll() não existir, ele usará o mecanismo seletor Sizzle para localizar manualmente o seletor que terá sua própria implementação. Assim, você pode ter pelo menos três implementações diferentes, todas na mesma família de navegadores, dependendo do seletor exato e do quão novo é o navegador. Em seguida, navegadores individuais terão suas próprias implementações querySelectorAll() . Se você quiser lidar com essa situação de maneira confiável, provavelmente terá que usar seu próprio código de iteração, como ilustrado acima.

O seletor de id do jQuery retorna apenas um resultado. O descendant e multiple seletores nas segunda e terceira declarações são projetados para selecionar vários elementos. É semelhante a:

Declaração 1

 var length = document.getElementById('a').length; 

… Produz um resultado.

Declaração 2

 var length = 0; for (i=0; i 

... Produz dois resultados.

Declaração 3

 var length = document.getElementById('a').length + document.getElementsByTagName('div').length; 

... Também produz dois resultados.

Na página do jQuery do seletor do id :

Cada valor de id deve ser usado apenas uma vez em um documento. Se mais de um elemento tiver recebido o mesmo ID, as consultas que usam esse ID só selecionarão o primeiro elemento correspondente no DOM. Este comportamento não deve ser invocado, no entanto; um documento com mais de um elemento usando o mesmo ID é inválido.

Google impertinente. Mas eles nem fecham suas tags e eu ouço. A questão é, no entanto, por que as segunda e terceira consultas de Misha retornam 2 e não 1 também.

Se você tiver vários elementos com o mesmo ID ou mesmo nome, basta atribuir a mesma class a esses elementos múltiplos e acessá-los por índice e executar a operação necessária.

  
1 2 3

JQ:

 $($(".demo")[0]).val("First span"); $($(".demo")[1]).val("Second span"); 

você pode simplesmente escrever $ (‘span # a’). length para obter o tamanho.

Aqui está a solução para o seu código:

 console.log($('span#a').length); 

tente JSfiddle: https://jsfiddle.net/vickyfor2007/wcc0ab5g/2/