¿Cómo seleccionar nodos html por ID con jquery cuando la identificación contiene un punto?

178

Si mi html se ve así:

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

¿Cómo puedo seleccionar # SearchBag.CompanyName con JQuery? No puedo hacer que funcione y me temo que es el punto lo que lo está rompiendo todo. Lo molesto es que renombrar todas mis identificaciones sería mucho trabajo, sin mencionar la pérdida de legibilidad.

Nota:
No comencemos a hablar sobre cómo las tablas no están hechas para el diseño. Soy muy consciente del valor y las deficiencias de CSS y trato de usarlo lo más posible.

Boris Callens
fuente
1
¿Es un punto en un ID incluso HTML válido?
cletus 03 de
77
Si. Los ID pueden contener '-', '_', '.' y ':'. w3.org/TR/html4/types.html#type-name
bobince 03 de
PEC, mis páginas validar todo a excepción de la etiqueta doble <title> del marco asp.net mvc genera ..
Boris Callens

Respuestas:

215

@Tomalak en comentarios:

dado que los selectores de ID deben ir precedidos de un hash #, no debe haber ambigüedad aquí

"# Id.class" es un selector válido que requiere una identificación y una clase separada para que coincida; Es válido y no siempre es totalmente redundante.

La forma correcta de seleccionar un literal '.' en CSS es escapar de él: "#id \ .moreid". Esto solía causar problemas en algunos navegadores antiguos (en particular IE5.x), pero todos los navegadores de escritorio modernos lo admiten.

El mismo método parece funcionar en jQuery 1.3.2, aunque no lo he probado a fondo; quickExpr no lo recoge, pero el analizador selector más involucrado parece acertar:

$('#SearchBag\\.CompanyName');
bobince
fuente
1
"# id.class es un selector válido que requiere una identificación y una clase separada para coincidir": según la especificación HTML, las ID deben ser únicas en todo el documento. ¿Para qué sería bueno "# id.class"? Quiero decir, no puedes ser más específico que "#id", ¿verdad?
Tomalak
2
@Tom: "# id.class" podría ser bueno para varios documentos que usan la misma hoja de estilo o configuran estados con secuencias de comandos del lado del cliente. Por ejemplo, "# navhome.navselected".
bobince 03 de
@bobince: Sí, a cletus se le ocurrió el mismo ejemplo, y creo que es válido. Todavía me parece extraño, y no puedo ver la verdadera ventaja de poder hacer eso. Especialmente a la luz de HTML que permite puntos en la ID y el hecho de que siempre puede usar ".navselected" para lograr lo mismo.
Tomalak
Es posible que, por ejemplo, desee que un #navhome seleccionado se ilumine en un color diferente al #navabout seleccionado, pero que se compartan otras propiedades seleccionadas .nav. No diría que esta situación surge todo el tiempo, pero ciertamente la he necesitado ocasionalmente.
bobince 03 de
3
Creo que la respuesta de @Tomalak es más elegante, como:$('[id="profile.birthdate"]')
dr.dimitru
118

Una variante sería esta:

$("input[id='SearchBag.CompanyName']")
Tomalak
fuente
1
En efecto. ¿Podría decirme por qué su solución funciona y $ ("# SearchBag.CompanyName") no?
Boris Callens
9
Porque .CompanyName se trata como un selector de clase.
cletus 03 de
2
Mirando rápidamente el código fuente, es una decisión de diseño deliberada o un error. La expresión regular utilizada para identificar los selectores de identificación (denominada quickExpr) no incluye el punto como un carácter válido. Sin embargo, la especificación HTML lo permite.
Tomalak
55
Posiblemente sea útil tener un selector de clase en una ID. Imagina que tienes un elemento #menu en cada página pero quieres que sea diferente en una de tus páginas. # menu.hideme por ejemplo? Marginal lo sé pero es válido.
cletus 03 de
2
Esta es claramente la respuesta superior. Funciona también con variables como esta: $ ("tr [id = '" + private_var + "']"). Css ("background-color", "#EEEEEE");
Steve K
33

No necesita escapar de nada si usa document.getElementById:

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

getElementById asume que la entrada es solo un atributo id, por lo que el punto no se interpretará como un selector de clase.

Licuadora
fuente
Solución ordenada, también funciona bien con ID dinámica que puede contener puntos
Cookalino
17

Respuesta corta : si tiene un elemento con id = "foo.bar", puede usar el selector$("#foo\\.bar")

Respuesta más larga : Esto es parte de la documentación de jquery - selectores de sección que puede encontrar aquí: http://api.jquery.com/category/selectors/

Su pregunta se responde justo al comienzo de la documentación:

Si desea utilizar cualquiera de los metacaracteres (como 
! "# $% & '() * +,. /:;? @ [\] ^` {|} ~) 
como parte literal de un nombre, debes escapar del personaje con 
dos barras invertidas: \\. Por ejemplo, si tiene un elemento con id = "foo.bar",
puede usar el selector $ ("# foo \\. bar"). La especificación CSS del W3C contiene
El conjunto completo de reglas sobre selectores CSS válidos. También es útil el
entrada de blog de Mathias Bynens sobre secuencias de escape de caracteres CSS para identificadores.
oneiros
fuente
44
Te das cuenta de que esta pregunta tiene más de tres años y la documentación puede no haber sido la misma entonces, ¿verdad?
Reimius
9

La selección de atributos parece ser apropiada cuando su ID está en una variable:

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

Esto está documentado en la API de selectores jQuery :

Para utilizar cualquiera de los meta-caracteres (tales como !"#$%&'()*+,./:;<=>?@[\]^`{|}~) como una parte literal de un nombre, hay que escapó con dos barras invertidas con: \\. Por ejemplo, un elemento con id="foo.bar", puede usar el selector $("#foo\\.bar").

En resumen, prefije el .con \\.

$('#SearchBag\\.CompanyName')

El problema es que .coincidirá con una clase, por $('#SearchBag.CompanyName')lo que coincidiría <div id="SearchBag" class="CompanyName">. El escapado \\.será tratado como normal .sin un significado especial, coincidiendo con la identificación que desee.

Esto se aplica a todos los caracteres !"#$%&'()*+,./:;<=>?@[\]^`{|}~que de otro modo tendrían un significado especial como selector en jQuery.

Jon Surrell
fuente
2

Chicos que buscan una solución más genérica, encontré una solución que inserta una barra hacia atrás antes de cualquier carácter especial, esto resuelve problemas relacionados con la recuperación de nombre e ID de un div que contiene caracteres especiales.

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

devuelve "Str1 \\. str2 \\% str3"

Espero que esto sea útil!

Abhishek
fuente
1

Puede usar un selector de atributos:

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

O puede especificar el tipo de elemento:

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