Como selecionar nós html por ID com jquery quando o ID contém um ponto?

178

Se meu html estivesse assim:

<td class="controlCell">
    <input class="inputText" id="SearchBag.CompanyName" name="SearchBag.CompanyName" type="text" value="" />
</td>

Como eu selecionei # SearchBag.CompanyName com JQuery? Não consigo fazê-lo funcionar e temo que seja o ponto que está quebrando tudo. O irritante é que renomear todos os meus IDs seria muito trabalhoso, sem mencionar a perda de legibilidade.

Nota:
Por favor, não vamos começar a falar sobre como as tabelas não são feitas para layout. Estou muito ciente do valor e das deficiências do CSS e tento usá-lo o máximo possível.

Boris Callens
fonte
1
Um período em um ID é válido em HTML?
Cletus
7
Sim. Os IDs podem conter '-', '_', '.' e ':'. w3.org/TR/html4/types.html#type-name
bobince
PEC, minhas páginas todos validar exceto para o tag dupla <title> do quadro asp.net mvc gera ..
Boris Callens

Respostas:

215

@Tomalak nos comentários:

como os seletores de ID devem ser precedidos por um hash #, não deve haver ambiguidade aqui

"# Id.class" é um seletor válido que requer que um id e uma classe separada correspondam; é válido e nem sempre totalmente redundante.

A maneira correta de selecionar um literal '.' em CSS é escapar: “#id \ .moreid”. Isso costumava causar problemas em alguns navegadores mais antigos (em particular o IE5.x), mas todos os navegadores de desktop modernos são compatíveis.

O mesmo método parece funcionar no jQuery 1.3.2, embora eu não o tenha testado completamente; O quickExpr não atende, mas o analisador de seletor mais envolvido parece acertar:

$('#SearchBag\\.CompanyName');
bobince
fonte
1
"# id.class é um seletor válido que requer um id e uma classe separada para corresponder": conforme a especificação HTML, os IDs devem ser únicos em todo o documento. Para que "# id.class" seria bom? Quero dizer, você não pode ser mais específico que "#id", pode?
Tomalak
2
@ Tom: “# id.class” pode ser bom para vários documentos usando a mesma folha de estilo ou definindo estados com scripts do lado do cliente. Por exemplo "# navhome.navselected".
bobince
@bince: Sim, cletus veio com o mesmo exemplo, e acho que é válido. Ainda me parece estranho, e não consigo ver a vantagem genuína de poder fazer isso. Especialmente à luz do HTML, permitindo pontos no ID e o fato de você sempre poder usar ".navselected" para obter o mesmo.
Tomalak
Você pode, por exemplo, desejar que um #navhome selecionado acenda com uma cor diferente de um #navabout selecionado, mas que outras propriedades .navselected sejam compartilhadas. Eu não diria que essa situação surge o tempo todo, mas certamente preciso disso ocasionalmente.
bobince
3
Eu acho que a resposta de @Tomalak é mais elegante, como:$('[id="profile.birthdate"]')
dr.dimitru 10/10
118

Uma variante seria esta:

$("input[id='SearchBag.CompanyName']")
Tomalak
fonte
1
De fato. Você poderia me dizer por que sua solução funciona e $ ("# SearchBag.CompanyName") não?
Boris Callens 03/03/2009
9
Porque .CompanyName é tratado como um seletor de classe.
Cletus
2
Olhando rapidamente para o código fonte, é uma decisão deliberada de design ou um bug. O regex usado para identificar seletores de ID (chamado quickExpr) não inclui o ponto como um caractere válido. A especificação HTML, no entanto, permite.
Tomalak
5
Ter um seletor de classe em um ID é possivelmente útil. Imagine que você tem um elemento #menu em todas as páginas, mas deseja torná-lo diferente em uma de suas páginas. # menu.hideme por exemplo? Marginal eu sei, mas é válido.
Cletus
2
Essa é claramente a resposta superior. Funciona também com variáveis ​​como esta: $ ("tr [id = '" + private_var + "']"). Css ("background-color", "#EEEEEE");
27540 Steve
33

Você não precisa escapar de nada se usar document.getElementById:

$(document.getElementById('strange.id[]'))

getElementById assume que a entrada é apenas um atributo id, portanto o ponto não será interpretado como um seletor de classe.

Liquidificador
fonte
Solução elegante, também funciona muito bem com ID dinâmica que podem conter pontos
Cookalino
17

Resposta curta : Se você possui um elemento com id = "foo.bar", pode usar o seletor$("#foo\\.bar")

Resposta mais longa : isso faz parte da documentação do jquery - seletores de seção que você pode encontrar aqui: http://api.jquery.com/category/selectors/

Sua pergunta é respondida logo no início da documentação:

Se você deseja usar qualquer um dos meta-caracteres (como 
! "# $% & '() * +,. /:;? @ [\] ^` {|} ~) 
como parte literal de um nome, você deve escapar do personagem com 
duas barras invertidas: \\. Por exemplo, se você tiver um elemento com id = "foo.bar",
você pode usar o seletor $ ("# foo \\. bar"). A especificação CSS do W3C contém
o conjunto completo de regras sobre seletores CSS válidos. Também é útil o
entrada do blog de Mathias Bynens em seqüências de escape de caracteres CSS para identificadores.
oneiros
fonte
4
Você percebe que essa pergunta tem mais de três anos e a documentação pode não ter sido a mesma, certo?
Reimius
9

A seleção de attr parece apropriada quando seu ID está em uma variável:

var id_you_want='foo.bar';
$('[id="' + id_you_want + '"]');
bispo
fonte
4

Isso está documentado na API de seletores do jQuery :

Para usar qualquer um dos meta-caracteres (tais como !"#$%&'()*+,./:;<=>?@[\]^`{|}~) como uma parte literal de um nome, deve ser escapado com com duas barras invertidas: \\. Por exemplo, um elemento com id="foo.bar", pode usar o seletor $("#foo\\.bar").

Em suma, prefixe o .com \\.

$('#SearchBag\\.CompanyName')

O problema é que .corresponderá a uma classe, portanto $('#SearchBag.CompanyName')corresponderá <div id="SearchBag" class="CompanyName">. Os que escaparam \\.serão tratados como normais, .sem significado especial, correspondendo ao ID que você deseja.

Isso se aplica a todos os caracteres !"#$%&'()*+,./:;<=>?@[\]^`{|}~que, de outra forma, teriam um significado especial como seletor no jQuery.

Jon Surrell
fonte
2

Caras que procuram uma solução mais genérica, encontrei uma solução que insere uma barra invertida antes de qualquer caractere especial, isso resolve problemas relacionados à recuperação de nome e ID de uma div que contém caracteres especiais.

"Str1.str2% str3" .replace (/ [^ \ w \ s] / gi, '\\ $ &')

retorna "Str1 \\. str2 \\% str3"

Espero que isso seja útil!

Abhishek
fonte
1

Você pode usar um seletor de atributos:

$("[id='SearchBag.CompanyName']");

Ou você pode especificar o tipo de elemento:

$("input[id='SearchBag.CompanyName']");
ntroccoli
fonte