Usando querySelector con ID que son números


94

Por lo que tengo entendido, la especificación HTML5 le permite usar ID que son números como este.

<div id="1"></div>
<div id="2"></div>

Puedo acceder a estos bien usando getElementByIdpero no con querySelector. Si intento hacer lo siguiente, obtengo SyntaxError: DOM Exception 12 en la consola.

document.querySelector("#1")

Solo tengo curiosidad por qué el uso de números como ID no funciona querySelectorcuando la especificación HTML5 dice que son válidos. Probé con varios navegadores.


1
No creo que la especificación HTML5 diga que son válidas. Lo comprobaré dos
beautifulcoder

3
@beautifulcoder Son válidos
dsgriffin

1
No importa, según validator.w3.org/check es válido utilizar números. ¿Quizás los navegadores modernos aún no han implementado el estándar?
beautifulcoder

Respuestas:


108

Es válido, pero requiere un manejo especial. Desde aquí: http://mathiasbynens.be/notes/css-escapes

Dígitos iniciales

Si el primer carácter de un identificador es numérico, deberá escaparlo según su punto de código Unicode. Por ejemplo, el punto de código para el carácter 1 es U + 0031, por lo que debería escapar como \ 000031 o \ 31.

Básicamente, para escapar de cualquier carácter numérico, simplemente antepóngalo con \ 3 y agregue un carácter de espacio (). ¡Yay Unicode!

Entonces su código terminaría como (CSS primero, JS segundo):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');

¿Cuál sería la sintaxis para valores superiores a 9? No puedo hacer que esto funcione con ID como 10.
Berry Blue

5
Necesita un espacio después del primer carácter: #\\31 0- puede hacer referencia a mothereffingcssescapes.com
Dennis

¡Gracias por el seguimiento y el enlace!
Berry Blue

1
Tenga en cuenta que el espacio solo es necesario si un carácter que es un dígito hexadecimal sigue inmediatamente a la secuencia de escape, para distinguir ese carácter de la secuencia de escape. Consulte w3.org/TR/CSS21/syndata.html#characters para obtener más detalles.
BoltClock

84

Porque si bien son válidos en la especificación HTML5, no son válidos en CSS, que es lo que significa " selector de consultas ".

En su lugar, tendría que hacer esto:, document.querySelector("[id='1']")que es muy largo considerando que podría darle una identificación significativa como message1o algo así;)


1
No "tienes que hacerlo": hay una manera de usar un selector de ID con un dígito inicial. Sin embargo, estoy de acuerdo en que es mejor tener una identificación significativa.
Dennis

9
Los UUID pueden empezar por un número.
Alfonso Nishikawa

20

Necesitaba un enfoque automatizado. Un cambio reciente significó que los valores de identificación utilizados ya no eran simples caracteres alfabéticos e incluían números y caracteres especiales.

Terminé usando CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

console.log(CSS.escape('1'));

Primero, este es el caso fallido:

const theId = "1";
document.querySelector(`#${theId}`);
const el = document.querySelector(`#${theId}`);
el.innerHTML = "After";
<div id="1">Before</div>

Y ahora usando CSS.escape:

const theId = "1";
const el = document.querySelector(`#${CSS.escape(theId)}`);
el.innerHTML = "After";
<div id="1">Before</div>

¡Vea cómo cambia correctamente para mostrar After, demostrando que el selector funcionó!


A partir de hoy, cuando necesite lidiar con alguna identificación extraña que no controla, esta es la solución más limpia, también porque es compatible con todos los navegadores modernos.
LasaleFamine

3

De la sintaxis de los selectores de atributos de la documentación del W3C

Los valores de atributo deben ser una cadena o identificadores CSS válidos.

Por tanto, los dígitos o las cadenas alfanuméricas con un dígito inicial no califican como un identificador válido.

Si está utilizando una utilidad generadora de ID para generar un identificador, puede terminar con identificadores alfanuméricos con dígitos iniciales.

Una solución rápida sería omitir dígitos del SEED del generador (si se puede modificar) o agregar siempre una cadena a la identificación generada.


2

Aquí hay una función que hice hace un momento para tratar con ID de números principales en los selectores de CSS, y es segura para IE como CSS.escape no lo es.

Pase el selector por esta función cleanSelector antes de usarlo:

var cleanSelector = function(selector){
    (selector.match(/(#[0-9][^\s:,]*)/g) || []).forEach(function(n){
        selector = selector.replace(n, '[id="' + n.replace("#", "") + '"]');
    });
    return selector;
};

var myselector = ".dog #980sada_as div span#aside:hover div.apple#05crab:nth-of-type(2), .ginger #2_green_div, div.cupcake #darwin p#23434-346365-53453";

var clean_myselector = cleanSelector(myselector);

// print to show difference
console.log(myselector);
console.log(clean_myselector);

//use the new selector like normal
var elems = document.querySelectorAll( clean_myselector ); 

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.