Подтвердить что ты не робот

How/why is "* [attribute ^ =" string "" действительный запросSelector? (Ошибка JS?)

Итак, это может быть ошибка... Я ошибся в CSS-пути, чтобы проверить, что элементы, которые были обработаны, имеют функцию onclick, начинающуюся с "ajaxLoad("

document.querySelectorAll( 'a[onclick^="ajaxLoad("' )

Как вы можете видеть, я забыл закрыть атрибут accessor с помощью ], например:

document.querySelectorAll( 'a[onclick^="ajaxLoad(]"' )

Как ни странно, это сработало!

Изменить - нет. Я не использовал правильный селектор CSS:

document.querySelectorAll( 'a[onclick^="ajaxLoad("]' )

... но, как упоминалось в комментариях, очевидно, что эта дополнительная опечатка также работает!

Это явно неверно. Я заметил это, когда я пришел добавить еще один тип ссылки, класса tc-link, и мне было интересно, могу ли я просто связать его, как в стилях CSS, как:

document.querySelectorAll( 'a[onclick^="ajaxLoad(", a.tc-link' )

Ответ заключается в том, что вы можете закрыть эту скобку, но не тогда, когда эта опечатка оставлена.

Uncaught DOMException: Не удалось выполнить 'querySelectorAll' в 'Document': 'a [onclick ^ = "ajaxLoad (", tc-link "не является допустимым селектором.

Он работает на ^=, $= и *=, и из того, что я вижу, не происходит в Firefox или Opera (и у меня нет других браузеров для тестирования).

Я думал, что это была языковая причуда сперва, но пересмотренный вопрос: может ли кто-нибудь определить, на каком уровне (DOM? V8? Er.. webkit? Я не знаю, что это такое) Javascript/код браузера это относится к тому, где оно может быть сообщено/исправлено?

4b9b3361

Ответ 1

Это основополагающее мнение и нигде не близко к окончательному ответу.

Браузеры чрезвычайно сложны. Готово! На них ничего не предсказуемо.

Сначала проанализируйте список ошибочных селекторов:

  • a[onclick^="ajaxLoad(" (отсутствует ])
  • a[onclick^="ajaxLoad(]" (отсутствует ])
  • a[onclick="" (отсутствует ])
  • a[onclick="][onclick (отсутствует "] или отсутствует " и ] на основе того, что вам нужно)
  • a[onclick=""][onclick (отсутствует ])
  • a[onclick=" (отсутствует "])
  • a[onclick (отсутствует ])
  • a:not([onclick] (отсутствует ))
  • a:not([onclick (отсутствует ]))
  • a:not([onclick=" (отсутствует "]))
  • a:nth-child(5):not([onclick=" (отсутствует "]))
  • a:-webkit-any(:not([onclick=" (отсутствует "])))

Пока это список. Я могу подтвердить, что они работают с Google Chrome 41.0.2272.89m в Windows 7.

Обратите внимание на шаблон?
Это просто: Chrome все еще может использовать там селектора для соответствия элементам, заполняя основные отсутствующие символы, но только в конце!
То, что отсутствует, настолько предсказуемо, что не требует слишком больших усилий для исправления.
Но не каждый селектор может/будет "фиксированным" (например: a,, можно зафиксировать добавлением *).

Это может быть ошибка или функция (ака, смущающая ошибка, представленная как функция), чтобы смягчить стремление к движку CSS.
Это также влияет на jQuery, поскольку jQuery использует Sizzle, если document.querySelectorAll() не существует или генерирует исключение.

Через некоторое время мы можем найти еще много.


Отказ от ответственности:

Это поведение не следует полагаться и может измениться в будущем.
Все это основано на недействительных селекторах и недопустимом синтаксисе (например, некоторых IE CSS Hacks для более старых версий).
ВСЕ рабочие селекторы в списке выше соответствуют спецификации.

Селектор "незафиксированный", приведенный в качестве примера (a,) работает в jQuery, но это не связано с этим вопросом.
По сути, jQuery выполнит его как a.

Ответ 2

Причина, по которой большинство браузеров принимает отсутствующую закрывающую скобку, состоит в том, что все они следуют одному и тому же алгоритму из спецификация CSS. Об этом говорится в Chromium bugtracker; здесь соответствующий отрывок из комментария который закрыл ошибку как WontFix:

Когда вы разбираете строку 'a [b = c' (из ссылки примера), синтаксический анализатор CSS превращает это в:

IDENT(A)
SIMPLE [ BLOCK:
    IDENT(B)
    DELIM(=)
    IDENT(C)

Тот факт, что квадрат квадратной скобки был закрыт, теряется. Вы можете думать об этом как о парсере "автоматическое закрытие всех незакрытых блоков". Если вы используете синтаксический анализатор, совместимый со спецификацией, то в буквальном смысле невозможно обнаружить незаблокированный блок, если вы специально не проводите отдельный синтаксический разбор только для этой цели.

(Я знаю, что я разбираю старый вопрос здесь, но поскольку это еще время от времени появляется, ссылка и объяснение может быть полезно.)