Utilizzo di querySelector con ID che sono numeri


94

Da quello che ho capito, la specifica HTML5 ti consente di utilizzare ID che sono numeri come questo.

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

Posso accedere a questi bene usando getElementByIdma non con querySelector. Se provo a fare quanto segue ottengo SyntaxError: DOM Exception 12 nella console.

document.querySelector("#1")

Sono solo curioso del motivo per cui l'utilizzo dei numeri come ID non funziona querySelectorquando le specifiche HTML5 dicono che sono validi. Ho provato più browser.


1
Non penso che le specifiche HTML5 dica che sono valide. Controllerò due volte ...
beautifulcoder

3
@beautifulcoder Sono validi
dsgriffin

1
Non importa, secondo validator.w3.org/check è valido usare i numeri. Forse i browser moderni non hanno implementato completamente lo standard?
beautifulcoder

Risposte:


108

È valido, ma richiede un trattamento speciale. Da qui: http://mathiasbynens.be/notes/css-escapes

Cifre iniziali

Se il primo carattere di un identificatore è numerico, dovrai eseguire l'escape in base al punto di codice Unicode. Ad esempio, il punto di codice per il carattere 1 è U + 0031, quindi dovresti eseguire l'escape come \ 000031 o \ 31.

Fondamentalmente, per eseguire l'escape di qualsiasi carattere numerico, basta anteporre \ 3 e aggiungere uno spazio (). Yay Unicode!

Quindi il tuo codice finirebbe come (CSS prima, JS secondo):

#\31  {
    background: hotpink;
}

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

Quale sarebbe la sintassi per valori maggiori di 9? Non riesco a farlo funzionare con ID come 10.
Berry Blue

5
Hai bisogno di uno spazio dopo il primo carattere: #\\31 0- puoi fare riferimento a mothereffingcssescapes.com
Dennis

Grazie per il follow-up e il collegamento!
Berry Blue

1
Si noti che lo spazio è necessario solo se un carattere che è una cifra esadecimale segue immediatamente la sequenza di escape, al fine di distinguere quel carattere dalla sequenza di escape. Vedi w3.org/TR/CSS21/syndata.html#characters per maggiori dettagli.
BoltClock

84

Perché sebbene siano validi nelle specifiche HTML5, non sono validi in CSS, che è il significato di " selettore di query ".

Invece, dovresti farlo:, document.querySelector("[id='1']")che è molto prolisso considerando che potresti dargli un ID significativo come message1o qualcosa del genere;)


1
Non "devi" - c'è un modo per utilizzare un selettore di id con una cifra iniziale. Sono d'accordo però che è meglio avere un ID significativo.
Dennis

9
Gli UUID possono iniziare con un numero.
Alfonso Nishikawa

20

Avevo bisogno di un approccio automatizzato. Una modifica recente ha significato che i valori id utilizzati non erano più semplici caratteri alfabetici e includevano numeri e caratteri speciali.

Ho finito per usare CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

Innanzitutto, questo è il caso fallito:

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

E ora usando CSS.escape:

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

Guarda come cambia correttamente per mostrare After, dimostrando che il selettore ha funzionato!


Ad oggi, quando hai a che fare con qualche id strano che non controlli, questa è la soluzione più pulita, anche perché supportata da tutti i browser moderni.
LasaleFamine

3

Dalla documentazione W3C Sintassi dei selettori di attributi

I valori degli attributi devono essere identificatori CSS validi o String.

Pertanto, le cifre o le stringhe alfanumeriche con la cifra iniziale non si qualificano come identificatori validi.

Se utilizzi un'utilità di generazione di ID per generare un identificatore, potresti ritrovarti con ID alfanumerici con cifre iniziali.

Una soluzione rapida sarebbe omettere le cifre dal SEED del generatore (se può essere modificato) o aggiungere sempre una stringa all'id generato.


2

Ecco una funzione che ho creato solo ora per gestire gli ID dei numeri iniziali nei selettori CSS, ed è IE sicura come CSS.escape non lo è.

Passa il selettore attraverso questa funzione cleanSelector prima di 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 ); 

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.