Utilisation de querySelector avec des ID qui sont des nombres

94

D'après ce que je comprends, les spécifications HTML5 vous permettent d'utiliser des identifiants qui sont des nombres comme celui-ci.

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

Je peux accéder à ces bons en utilisant getElementByIdmais pas avec querySelector. Si j'essaye de faire ce qui suit, j'obtiens SyntaxError: DOM Exception 12 dans la console.

document.querySelector("#1")

Je suis juste curieux de savoir pourquoi l'utilisation de nombres comme identifiants ne fonctionne pas querySelectorlorsque la spécification HTML5 indique qu'ils sont valides. J'ai essayé plusieurs navigateurs.

Bleu baie
la source
1
Je ne pense pas que les spécifications HTML5 indiquent qu'elles sont valides. Je vais vérifier ...
beautifulcoder
3
@beautifulcoder Ils sont valides
dsgriffin
1
Nevermind, selon validator.w3.org/check, il est valide d'utiliser des nombres. Peut-être que les navigateurs modernes n'ont pas tout à fait implémenté la norme?
beautifulcoder

Réponses:

108

Il est valide, mais nécessite un traitement spécial. De là: http://mathiasbynens.be/notes/css-escapes

Chiffres principaux

Si le premier caractère d'un identifiant est numérique, vous devrez l'échapper en fonction de son point de code Unicode. Par exemple, le point de code pour le caractère 1 est U + 0031, vous devez donc l'échapper comme \ 000031 ou \ 31.

Fondamentalement, pour échapper à tout caractère numérique, préfixez-le simplement avec \ 3 et ajoutez un caractère d'espace (). Yay Unicode!

Donc, votre code finirait par (CSS d'abord, JS ensuite):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');
Dennis
la source
Quelle serait la syntaxe pour les valeurs supérieures à 9? Je ne peux pas faire fonctionner cela avec des identifiants comme 10.
Berry Blue
5
Vous avez besoin d'un espace après le premier caractère: #\\31 0- vous pouvez vous référer à mothereffingcssescapes.com
Dennis
Merci pour le suivi et le lien!
Berry Blue
1
Notez que l'espace n'est nécessaire que si un caractère qui est un chiffre hexadécimal suit immédiatement la séquence d'échappement, afin de distinguer ce caractère de la séquence d'échappement. Voir w3.org/TR/CSS21/syndata.html#characters pour plus de détails.
BoltClock
83

Parce que bien qu'ils soient valides dans la spécification HTML5, ils ne le sont pas dans CSS, c'est ce que signifie " sélecteur de requête ".

Au lieu de cela, vous devriez faire ceci:, ce document.querySelector("[id='1']")qui est très long étant donné que vous pourriez lui donner un identifiant significatif comme message1ou quelque chose;)

Niet the Dark Absol
la source
1
Vous n'êtes pas "obligé" - il existe un moyen d'utiliser un sélecteur d'identifiant avec un chiffre en tête. Je conviens cependant qu'il vaut mieux avoir une identité significative.
Dennis
9
Les UUID peuvent commencer par un nombre.
Alfonso Nishikawa
20

J'avais besoin d'une approche automatisée. Un changement récent signifiait que les valeurs d'identifiant utilisées n'étaient plus de simples caractères alphabétiques et incluaient des nombres et des caractères spéciaux.

J'ai fini par utiliser CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

Tout d'abord, voici le cas défaillant:

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

Et maintenant en utilisant CSS.escape:

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

Voyez comment cela change correctement pour montrer After, démontrant que le sélecteur a fonctionné!

Glavin001
la source
À partir d'aujourd'hui, lorsque vous devez gérer un identifiant étrange que vous ne contrôlez pas, c'est la solution la plus propre, également parce qu'elle est prise en charge par tous les navigateurs modernes.
LasaleFamine le
3

Depuis la documentation du W3C Syntaxe des sélecteurs d'attributs

Les valeurs d'attribut doivent être des identifiants CSS ou une chaîne valides.

Ainsi, les chiffres ou les chaînes alphanumériques avec le premier chiffre ne sont pas considérés comme un identifiant valide.

Si vous utilisez un utilitaire de génération d'ID pour générer un identifiant, vous risquez de vous retrouver avec des identifiants alphanumériques avec des chiffres en tête.

Une solution rapide serait soit d'omettre les chiffres du SEED du générateur (s'il peut être modifié), soit de toujours ajouter une chaîne à l'identifiant généré.

vikash Mishra
la source
2

Voici une fonction que j'ai créée tout à l'heure pour traiter les ID de numéro de tête dans les sélecteurs CSS, et elle est sûre pour IE, contrairement à CSS.escape.

Passez le sélecteur à travers cette fonction cleanSelector avant de l'utiliser:

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 ); 


Par
la source