Comment sélectionner des nœuds html par ID avec jquery lorsque l'ID contient un point?

178

Si mon html ressemblait à ceci:

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

Comment puis-je sélectionner # SearchBag.CompanyName avec JQuery? Je ne peux pas le faire fonctionner et j'ai peur que ce soit le point qui brise tout. Le plus ennuyeux est que renommer tous mes identifiants serait beaucoup de travail, sans parler de la perte de lisibilité.

Remarque:
veuillez ne pas commencer à parler du fait que les tableaux ne sont pas conçus pour la mise en page. Je suis très conscient de la valeur et des lacunes du CSS et j'essaie de l'utiliser autant que possible.

Boris Callens
la source
1
Un point dans un identifiant est-il même valide en HTML?
cletus
7
Oui. Les identifiants peuvent contenir «-», «_», «.» et ':'. w3.org/TR/html4/types.html#type-name
bobince
Jeps, mes pages sont toutes validées à l'exception de la double balise <title> générée par le framework asp.net mvc ..
Boris Callens

Réponses:

215

@Tomalak dans les commentaires:

comme les sélecteurs d'ID doivent être précédés d'un hash #, il ne devrait y avoir aucune ambiguïté ici

«# Id.class» est un sélecteur valide qui nécessite à la fois un identifiant et une classe distincte pour correspondre; c'est valide et pas toujours totalement redondant.

La bonne façon de sélectionner un littéral «.» en CSS est d'y échapper: «#id \ .moreid». Cela causait des problèmes dans certains navigateurs plus anciens (en particulier IE5.x), mais tous les navigateurs de bureau modernes le prennent en charge.

La même méthode semble fonctionner dans jQuery 1.3.2, même si je ne l'ai pas testée à fond; quickExpr ne le prend pas, mais l'analyseur de sélecteur le plus impliqué semble bien faire les choses:

$('#SearchBag\\.CompanyName');
bobince
la source
1
"# id.class est un sélecteur valide qui nécessite à la fois un identifiant et une classe distincte pour correspondre": conformément aux spécifications HTML, les identifiants doivent être uniques dans tout le document. À quoi sert "# id.class"? Je veux dire, vous ne pouvez pas être plus précis que "#id", n'est-ce pas?
Tomalak
2
@Tom: «# id.class» peut convenir à plusieurs documents utilisant la même feuille de style ou à la définition d'états avec des scripts côté client. Par exemple «# navhome.navselected».
bobince
@bobince: Ouais, Cletus a proposé le même exemple, et je suppose que c'est valable. Pourtant, cela me semble étrange, et je ne vois pas le véritable avantage de pouvoir le faire. Surtout à la lumière du HTML autorisant des points dans l'ID et du fait que vous pouvez toujours utiliser ".navselected" pour obtenir la même chose.
Tomalak
Vous pouvez, par exemple, souhaiter qu'un #navhome sélectionné s'allume dans une couleur différente de celle d'un #navabout sélectionné, mais que d'autres propriétés .navselected soient partagées. Je ne dirais pas que cette situation survient tout le temps, mais j'en ai certainement besoin de temps en temps.
bobince
3
Je pense que la réponse de @Tomalak est plus élégante, comme:$('[id="profile.birthdate"]')
dr.dimitru
118

Une variante serait la suivante:

$("input[id='SearchBag.CompanyName']")
Tomalak
la source
1
En effet. Pouvez-vous me dire pourquoi votre solution fonctionne et $ ("# SearchBag.CompanyName") ne fonctionne pas?
Boris Callens
9
Parce que .CompanyName est traité comme un sélecteur de classe.
cletus
2
En regardant rapidement le code source, il s'agit soit d'une décision de conception délibérée, soit d'un bogue. L'expression régulière utilisée pour identifier les sélecteurs d'identifiant (nommés quickExpr) n'inclut pas le point comme caractère valide. La spécification HTML le permet cependant.
Tomalak
5
Avoir un sélecteur de classe sur un ID est peut-être utile. Imaginez que vous ayez un élément #menu sur chaque page mais que vous vouliez le rendre différent sur l'une de vos pages. # menu.hideme par exemple? Marginal je sais mais c'est valable.
cletus
2
C'est clairement la meilleure réponse. Fonctionne aussi avec des variables comme celle-ci: $ ("tr [id = '" + private_var + "']"). Css ("background-color", "#EEEEEE");
Steve K
33

Vous n'avez besoin d'échapper à rien si vous utilisez document.getElementById:

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

getElementById suppose que l'entrée est juste un attribut id, donc le point ne sera pas interprété comme un sélecteur de classe.

Mixeur
la source
Solution soignée, fonctionne également bien avec un ID dynamique qui peut contenir des points
Cookalino
17

Réponse courte : Si vous avez un élément avec id = "foo.bar", vous pouvez utiliser le sélecteur$("#foo\\.bar")

Réponse plus longue : Cela fait partie de la documentation jquery - sélecteurs de section que vous pouvez trouver ici: http://api.jquery.com/category/selectors/

Votre question est répondue dès le début de la documentation:

Si vous souhaitez utiliser l'un des méta-caractères (tels que 
! "# $% & '() * +,. /:;? @ [\] ^` {|} ~) 
comme partie littérale d'un nom, vous devez échapper au caractère avec 
deux contre-obliques: \\. Par exemple, si vous avez un élément avec id = "foo.bar",
vous pouvez utiliser le sélecteur $ ("# foo \\. bar"). La spécification CSS W3C contient
l'ensemble complet de règles concernant les sélecteurs CSS valides. Le
article de blog de Mathias Bynens sur les séquences d'échappement de caractères CSS pour les identificateurs.
oniros
la source
4
Vous réalisez que cette question remonte à plus de trois ans et que la documentation n'était peut-être pas la même à l'époque, n'est-ce pas?
Reimius
9

La sélection attr semble appropriée lorsque votre identifiant est dans une variable:

var id_you_want='foo.bar';
$('[id="' + id_you_want + '"]');
évêque
la source
4

Ceci est documenté dans l' API des sélecteurs jQuery :

Pour utiliser les méta-caractères ( par exemple !"#$%&'()*+,./:;<=>?@[\]^`{|}~) comme une partie littérale d'un nom, il doit être échappé avec deux barres obliques inverses: \\. Par exemple, un élément avec id="foo.bar", peut utiliser le sélecteur $("#foo\\.bar").

En bref, préfixez le .avec \\.

$('#SearchBag\\.CompanyName')

Le problème est que .cela correspondra à une classe, donc $('#SearchBag.CompanyName')correspondrait <div id="SearchBag" class="CompanyName">. L'échappée avec \\.sera traitée comme une valeur normale .sans signification particulière, correspondant à l'ID que vous désirez.

Cela s'applique à tous les caractères !"#$%&'()*+,./:;<=>?@[\]^`{|}~qui auraient autrement une signification particulière en tant que sélecteur dans jQuery.

Jon Surrell
la source
2

Les gars qui recherchent une solution plus générique, j'ai trouvé une solution qui insère une barre oblique arrière avant tout caractère spécial, cela résout les problèmes liés à la récupération du nom et de l'ID d'un div contenant des caractères spéciaux.

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

renvoie "Str1 \\. str2 \\% str3"

J'espère que c'est utile!

Abhishek
la source
1

Vous pouvez utiliser un sélecteur d'attribut:

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

Ou vous pouvez spécifier le type d'élément:

$("input[id='SearchBag.CompanyName']");
ntrocoli
la source