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/