Как выбрать узлы HTML по идентификатору с jquery, когда идентификатор содержит точку?

178

Если мой HTML выглядит так:

<td class="controlCell">
    <input class="inputText" id="SearchBag.CompanyName" name="SearchBag.CompanyName" type="text" value="" />
</td>

Как я могу выбрать # SearchBag.CompanyName с JQuery? Я не могу заставить это работать, и я боюсь, что это - точка, которая ломает все это. Раздражает то, что переименование всех моих идентификаторов будет большой работой, не говоря уже о потере читабельности.

Примечание:
пожалуйста, давайте не будем говорить о том, как таблицы не созданы для разметки. Я прекрасно осознаю ценность и недостатки CSS и стараюсь максимально использовать его.

Борис Калленс
источник
1
Является ли точка в идентификаторе верным HTML?
Клет
7
Да. Идентификаторы могут содержать '-', '_', '.' и ':'. w3.org/TR/html4/types.html#type-name
bobince,
Jeps, все мои страницы проверяются, за исключением двойного тега <title>, который генерирует фреймворк asp.net mvc ..
Борис Калленс

Ответы:

215

@ Томалак в комментариях:

поскольку селекторам идентификаторов должен предшествовать хэш #, здесь не должно быть никакой двусмысленности

«# Id.class» - допустимый селектор, для которого требуется соответствие как идентификатора, так и отдельного класса; это действительно и не всегда полностью избыточно.

Правильный способ выбора литерала "." в CSS это избежать: «#id \ .moreid». Раньше это вызывало проблемы в некоторых старых браузерах (в частности, IE5.x), но все современные браузеры для настольных компьютеров поддерживают его.

Похоже, что тот же метод работает в jQuery 1.3.2, хотя я не проверял его полностью; quickExpr не подхватывает его, но более сложный синтаксический анализатор выбора, кажется, делает это правильно:

$('#SearchBag\\.CompanyName');
bobince
источник
1
«# id.class является допустимым селектором, для которого требуется соответствие как идентификатора, так и отдельного класса»: согласно спецификации HTML идентификаторы должны быть уникальными во всем документе. Для чего подойдет "# id.class"? Я имею в виду, вы не можете быть более конкретным, чем "#id", не так ли?
Томалак
2
@Tom: «# id.class» может быть полезен для нескольких документов, использующих одну и ту же таблицу стилей или устанавливающих состояния с помощью сценариев на стороне клиента. Например, «# navhome.navselected».
бобинце
@bobince: Да, Клетус придумал тот же пример, и я уверен, что он действителен. Тем не менее мне это кажется странным, и я не вижу подлинного преимущества в том, что я могу это сделать. Особенно в свете HTML, разрешающего точки в идентификаторе, и того факта, что вы всегда можете использовать «.navselected» для достижения того же самого.
Томалак
Например, вы можете захотеть, чтобы выбранный #navhome загорелся другим цветом по сравнению с выбранным #navabout, но другие свойства .navselected будут доступны для совместного использования. Я бы не сказал, что такая ситуация возникает постоянно, но я, конечно, иногда нуждался в этом.
bobince
3
Я думаю, что ответ @Tomalak более элегантный, как:$('[id="profile.birthdate"]')
dr.dimitru
118

Один вариант будет таким:

$("input[id='SearchBag.CompanyName']")
Томалак
источник
1
На самом деле. Не могли бы вы сказать мне, почему ваше решение работает, а $ ("# SearchBag.CompanyName") - нет?
Борис Калленс
9
Потому что .CompanyName рассматривается как селектор класса.
Клет
2
Быстро просматривая исходный код, это либо обдуманное дизайнерское решение, либо ошибка. Регулярное выражение, используемое для идентификации селекторов идентификаторов (с именем quickExpr), не содержит точку в качестве допустимого символа. Спецификация HTML, однако, позволяет это.
Томалак
5
Наличие селектора класса на идентификаторе, возможно, полезно. Представьте, что у вас есть элемент #menu на каждой странице, но вы хотите изменить его на одной из ваших страниц. # menu.hideme например? Маргинал я знаю, но это действительно.
Клет
2
Это явно лучший ответ. Работает также с такими переменными: $ ("tr [id = '" + private_var + "']"). Css ("background-color", "#EEEEEE");
Стив К
33

Вам не нужно ничего избегать, если вы используете document.getElementById:

$(document.getElementById('strange.id[]'))

getElementById предполагается, что входные данные являются просто атрибутом id, поэтому точка не будет интерпретироваться как селектор класса.

смеситель
источник
Оптимальное решение, также хорошо работает с динамическим идентификатором, который может содержать точки
Cookalino
17

Краткий ответ : если у вас есть элемент с id = "foo.bar", вы можете использовать селектор$("#foo\\.bar")

Более длинный ответ : это часть документации jquery - селекторы разделов, которые вы можете найти здесь: http://api.jquery.com/category/selectors/

На ваш вопрос ответят в самом начале документации:

Если вы хотите использовать любой из метасимволов (например, 
! "# $% & '() * +,. /:;? @ [\] ^` {|} ~) 
как буквальная часть имени, вы должны экранировать 
две обратные косые черты: \\. Например, если у вас есть элемент с id = "foo.bar",
Вы можете использовать селектор $ ("# foo \\. bar"). Спецификация W3C CSS содержит
полный набор правил, касающихся действительных селекторов CSS. Также полезным является
запись в блоге Mathias Bynens о escape-последовательностях символов CSS для идентификаторов.
Oneiros
источник
4
Вы понимаете, что этому вопросу уже более трех лет, и документация, возможно, не была такой же, верно?
Реймиус
9

Выбор attr кажется подходящим, когда ваш идентификатор находится в переменной:

var id_you_want='foo.bar';
$('[id="' + id_you_want + '"]');
епископ
источник
4

Это задокументировано в API селекторов jQuery :

Для того, чтобы использовать любого из мета-символы (например , как !"#$%&'()*+,./:;<=>?@[\]^`{|}~) , как буквальная часть имени, он должен быть экранирован с двойной косой чертой: \\. Например, элемент с id="foo.bar", может использовать селектор $("#foo\\.bar").

Короче, префикс .с \\.

$('#SearchBag\\.CompanyName')

Проблема в том, что .будет соответствовать класс, поэтому $('#SearchBag.CompanyName')будет соответствовать <div id="SearchBag" class="CompanyName">. Экранированный символ \\.будет рассматриваться как обычный, .без особого значения, соответствующего желаемому идентификатору.

Это относится ко всем символам, !"#$%&'()*+,./:;<=>?@[\]^`{|}~которые в противном случае имели бы особое значение как селектор в jQuery.

Джон Суррелл
источник
2

Ребята, которые ищут более общее решение, я нашел одно решение, которое вставляет одну обратную косую черту перед любыми специальными символами, это решает проблемы, связанные с получением имени и идентификатора из div, который содержит специальные символы.

"Str1.str2% str3" .replace (/ [^ \ w \ s] / gi, '\\ $ &')

возвращает "Str1 \\. str2 \\% str3"

Надеюсь, это полезно!

Абхишек
источник
1

Вы можете использовать селектор атрибута:

$("[id='SearchBag.CompanyName']");

Или вы можете указать тип элемента:

$("input[id='SearchBag.CompanyName']");
ntroccoli
источник