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.

Niebieska Jagoda
źródło
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 ');
Dennis
źródło
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;)

Niet the Dark Absol
źródło
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!

Glavin001
źródło
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.

Vikash Mishra
źródło
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 ); 


Za
źródło