Używanie querySelector z identyfikatorami będącymi liczbami


99

Z tego, co rozumiem, specyfikacja HTML5 umożliwia używanie identyfikatorów, które są liczbami takimi jak ta.

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

Mogę uzyskać dostęp do tych dobrze za pomocą, getElementByIdale nie za pomocą querySelector. Jeśli spróbuję wykonać następujące czynności, w konsoli pojawi się SyntaxError: DOM Exception 12 .

document.querySelector("#1")

Jestem po prostu ciekawy, dlaczego używanie liczb jako identyfikatorów nie działa, querySelectorgdy specyfikacja HTML5 mówi, że są one prawidłowe. Próbowałem wielu przeglądarek.


1
Myślę, że specyfikacja HTML5 nie mówi, że są one prawidłowe. Jeszcze raz sprawdzę ...
beautifulcoder

3
@beautifulcoder Są ważne
dsgriffin

1
Nieważne, według validator.w3.org/check można używać liczb. Może nowoczesne przeglądarki nie zaimplementowały standardu?
beautifulcoder

Odpowiedzi:


112

Jest ważny, ale wymaga specjalnej obsługi. Stąd: http://mathiasbynens.be/notes/css-escapes

Wiodące cyfry

Jeśli pierwszy znak identyfikatora jest liczbą, musisz zmienić jego znaczenie na podstawie jego punktu kodowego Unicode. Na przykład punkt kodowy dla znaku 1 to U + 0031, więc możesz go zmienić jako \ 000031 lub \ 31.

Zasadniczo, aby uciec przed jakimkolwiek znakiem numerycznym, po prostu poprzedz go \ 3 i dołącz spację (). Yay Unicode!

Więc twój kod skończy jako (najpierw CSS, potem JS):

#\31  {
    background: hotpink;
}

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

Jaka byłaby składnia dla wartości większych niż 9? Nie mogę tego zmusić do pracy z identyfikatorami takimi jak 10.
Berry Blue

5
Potrzebujesz spacji po pierwszym znaku: #\\31 0- możesz odnieść się do mothereffingcssescapes.com
Dennis

Dziękuję za kontynuację i link!
Berry Blue

1
Zauważ, że spacja jest konieczna tylko wtedy, gdy znak będący cyfrą szesnastkową następuje bezpośrednio po sekwencji sterującej, w celu odróżnienia tego znaku od sekwencji sterującej. Więcej informacji można znaleźć pod adresem w3.org/TR/CSS21/syndata.html#characters .
BoltClock

85

Ponieważ chociaż są prawidłowe w specyfikacji HTML5, nie są poprawne w CSS, co oznacza „ selektor zapytania ”.

Zamiast tego musiałbyś to zrobić:, document.querySelector("[id='1']")co jest bardzo rozwlekłe, biorąc pod uwagę, że możesz nadać mu znaczący identyfikator message1lub coś takiego;)


1
Nie musisz tego robić - istnieje sposób na użycie selektora id z początkową cyfrą. Zgadzam się jednak, że lepiej mieć znaczący identyfikator.
Dennis

9
Identyfikatory UUID mogą zaczynać się od liczby.
Alfonso Nishikawa

25

Potrzebowałem podejścia, które byłoby zautomatyzowane. Niedawna zmiana oznaczała, że ​​używane wartości identyfikatorów nie były już prostymi znakami alfabetycznymi i zawierały liczby i znaki specjalne.

Skończyło się na CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

Po pierwsze, jest to przypadek niepowodzenia:

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

A teraz używając CSS.escape:

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

Zobacz, jak poprawnie zmienia się wyświetlanie After, demonstrując działanie selektora!


Na dzień dzisiejszy, gdy musisz poradzić sobie z jakimś dziwnym identyfikatorem, którego nie kontrolujesz, jest to najczystsze rozwiązanie, również dlatego, że jest obsługiwane przez wszystkie nowoczesne przeglądarki.
LasaleFamine

Świetne rozwiązanie, wykorzystując to w produkcji.
LoopsGod

3

Z dokumentacji W3C Składnia selektorów atrybutów

Wartości atrybutów muszą być prawidłowymi identyfikatorami CSS lub ciągiem znaków.

W związku z tym cyfry lub ciągi alfanumeryczne z cyfrą wiodącą nie kwalifikują się jako prawidłowy identyfikator.

Jeśli używasz narzędzia do generowania identyfikatorów do generowania identyfikatorów, możesz otrzymać identyfikatory alfanumeryczne z początkowymi cyframi.

Szybkim rozwiązaniem byłoby pominięcie cyfr z SEED generatora (jeśli można je zmodyfikować) lub zawsze dołączanie ciągu do wygenerowanego identyfikatora.


2

Oto funkcja, którą właśnie stworzyłem, aby radzić sobie z wiodącymi identyfikatorami liczbowymi w selektorach CSS i jest bezpieczna dla IE, tak jak CSS.escape nie.

Przeprowadź selektor przez tę funkcję cleanSelector przed jej użyciem:

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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.