Использование querySelector с идентификаторами, которые являются числами

98

Насколько я понимаю, спецификация HTML5 позволяет использовать идентификаторы, которые являются числами, подобными этому.

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

Я могу получить доступ к ним с помощью, getElementByIdно не с помощью querySelector. Если я попытаюсь сделать следующее, я получу SyntaxError: DOM Exception 12 в консоли.

document.querySelector("#1")

Мне просто любопытно, почему использование чисел в качестве идентификаторов не работает, querySelectorесли в спецификации HTML5 указано, что они действительны. Я пробовал несколько браузеров.

Берри Блю
источник
1
Я не думаю, что спецификация HTML5 утверждает, что они действительны. Я перепроверяю ...
beautifulcoder
3
@beautifulcoder Они действительны
dsgriffin
1
Неважно, согласно validator.w3.org/check, можно использовать числа. Может быть, современные браузеры еще не реализовали стандарт?
beautifulcoder

Ответы:

111

Это верно, но требует особого обращения. Отсюда: http://mathiasbynens.be/notes/css-escapes

Ведущие цифры

Если первый символ идентификатора числовой, вам нужно будет экранировать его на основе его кодовой точки Unicode. Например, кодовая точка для символа 1 - U + 0031, поэтому вы должны экранировать ее как \ 000031 или \ 31.

В основном, чтобы избежать любого числового символа, просто добавьте к нему префикс \ 3 и добавьте пробел (). Ура Юникод!

Таким образом, ваш код будет выглядеть следующим образом (сначала CSS, затем JS):

#\31  {
    background: hotpink;
}

document.getElementById('1');
document.querySelector('#\\31 ');
Деннис
источник
Каким будет синтаксис для значений больше 9? Я не могу заставить это работать с идентификаторами типа 10.
Berry Blue
5
Вам нужен пробел после первого символа: #\\31 0- вы можете ссылаться на mothereffingcssescapes.com
Деннис
Спасибо за продолжение и ссылку!
Berry Blue
1
Обратите внимание, что пробел необходим только в том случае, если за escape-последовательностью следует символ, являющийся шестнадцатеричной цифрой, чтобы отличить этот символ от escape-последовательности. См. W3.org/TR/CSS21/syndata.html#characters для получения дополнительной информации.
BoltClock
85

Потому что, хотя они действительны в спецификации HTML5, они не действительны в CSS, что означает « селектор запросов ».

Вместо этого вам придется сделать это:, document.querySelector("[id='1']")что очень многословно, учитывая, что вы могли бы дать ему значимый идентификатор, например, message1или что-то в этом роде;)

Ниет Темный Абсол
источник
1
Вам не «нужно» - есть способ использовать селектор идентификаторов с ведущей цифрой. Я согласен с тем, что лучше иметь значимый идентификатор.
Деннис
9
UUID могут начинаться с числа.
Альфонсо Нисикава
24

Мне нужен был автоматизированный подход. Недавнее изменение означало, что используемые значения id больше не были простыми буквенными символами и включали числа и специальные символы.

В итоге я использовал CSS.escape: https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape

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

Во-первых, это неудачный случай:

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

А теперь используя CSS.escape:

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

Посмотрите, как он правильно меняется, чтобы показать After, демонстрируя, что селектор работает!

Главин001
источник
На сегодняшний день, когда вам нужно иметь дело с каким-то странным идентификатором, который вы не контролируете, это наиболее чистое решение, в том числе потому, что оно поддерживается всеми современными браузерами.
LasaleFamine
Отличное решение, использующее это в производстве.
LoopsGod
3

Из документации W3C Синтаксис селекторов атрибутов

Значения атрибутов должны быть действительными идентификаторами CSS или String.

Таким образом, цифры или буквенно-цифровые строки с ведущей цифрой не считаются допустимым идентификатором.

Если вы используете утилиту генератора идентификаторов для генерации идентификатора, вы можете получить буквенно-цифровые идентификаторы с ведущими цифрами.

Быстрое решение - либо опустить цифры из SEED генератора (если его можно изменить), либо всегда добавлять строку к сгенерированному идентификатору.

Викаш Мишра
источник
2

Вот функция, которую я только что сделал для работы с идентификаторами ведущих чисел в селекторах CSS, и она безопасна для IE, в отличие от CSS.escape.

Перед использованием передайте селектор через эту функцию cleanSelector:

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


За
источник