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/код браузера это относится к тому, где оно может быть сообщено/исправлено?
Ответы
Ответ 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)
Тот факт, что квадрат квадратной скобки был закрыт, теряется. Вы можете думать об этом как о парсере "автоматическое закрытие всех незакрытых блоков". Если вы используете синтаксический анализатор, совместимый со спецификацией, то в буквальном смысле невозможно обнаружить незаблокированный блок, если вы специально не проводите отдельный синтаксический разбор только для этой цели.
(Я знаю, что я разбираю старый вопрос здесь, но поскольку это еще время от времени появляется, ссылка и объяснение может быть полезно.)