Jak wybrać węzły HTML według identyfikatora za pomocą jquery, gdy identyfikator zawiera kropkę?

178

Jeśli mój HTML wyglądałby tak:

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

Jak mogę wybrać # SearchBag.CompanyName za pomocą JQuery? Nie mogę zmusić go do działania i obawiam się, że to kropka to wszystko psuje. Irytujące jest to, że zmiana nazwy wszystkich moich identyfikatorów byłaby dużo pracy, nie wspominając o utracie czytelności.

Uwaga:
nie zaczynajmy mówić o tym, w jaki sposób tabele nie są tworzone do tworzenia układów. Jestem bardzo świadomy wartości i wad CSS i staram się z niego korzystać w jak największym stopniu.

Boris Callens
źródło
1
Czy kropka w identyfikatorze jest nawet poprawnym kodem HTML?
cletus
7
Tak. Identyfikatory mogą zawierać „-”, „_”, „.” i ':'. w3.org/TR/html4/types.html#type-name
bobince
Jeps, wszystkie moje strony sprawdzają poprawność, z wyjątkiem podwójnego znacznika <title> generowanego przez asp.net mvc framework ..
Boris Callens

Odpowiedzi:

215

@Tomalak w komentarzach:

ponieważ selektory identyfikatorów muszą być poprzedzone hashem #, nie powinno być tutaj dwuznaczności

„# Id.class” to prawidłowy selektor, który wymaga zarówno identyfikatora, jak i oddzielnej klasy, aby dopasować; jest ważny i nie zawsze całkowicie zbędny.

Prawidłowy sposób wyboru literału „”. w CSS jest to: „#id \ .moreid”. Powodowało to problemy w niektórych starszych przeglądarkach (w szczególności IE5.x), ale wszystkie nowoczesne przeglądarki stacjonarne obsługują to.

Ta sama metoda wydaje się działać w jQuery 1.3.2, chociaż nie przetestowałem jej dokładnie; quickExpr nie odbiera go, ale wydaje się, że bardziej zaangażowany parser selektora go poprawnie:

$('#SearchBag\\.CompanyName');
Bobin
źródło
1
„# id.class to prawidłowy selektor, który wymaga zarówno identyfikatora, jak i oddzielnej klasy, aby dopasować”: zgodnie ze specyfikacją HTML identyfikatory muszą być unikalne w całym dokumencie. Do czego służy „# id.class”? To znaczy, nie możesz być bardziej szczegółowy niż „#id”, prawda?
Tomalak
2
@Tom: „# id.class” może być dobre dla wielu dokumentów przy użyciu tego samego arkusza stylów lub ustawiania stanów za pomocą skryptów po stronie klienta. Na przykład „# navhome.navselected”.
Bob
@ bobince: Tak, Cletus wymyślił ten sam przykład i chyba to jest poprawne. Nadal wydaje mi się to dziwne i nie widzę prawdziwej korzyści z tego, że mogę to zrobić. Zwłaszcza w świetle HTML zezwalającego na kropki w identyfikatorze oraz na fakt, że zawsze można użyć „.navselected”, aby osiągnąć to samo.
Tomalak
Możesz na przykład chcieć, aby wybrany #navhome świecił innym kolorem niż wybrany #navabout, ale inne wybrane właściwości .navh mają być udostępniane. Nie powiedziałbym, że ta sytuacja ciągle się pojawia, ale z pewnością potrzebowałem jej od czasu do czasu.
bobince
3
Myślę, że odpowiedź @ Tomalak jest bardziej elegancka, na przykład:$('[id="profile.birthdate"]')
dr.dimitru,
118

Jeden wariant byłby następujący:

$("input[id='SearchBag.CompanyName']")
Tomalak
źródło
1
W rzeczy samej. Czy możesz mi powiedzieć, dlaczego Twoje rozwiązanie działa, a $ („# SearchBag.CompanyName”) nie?
Boris Callens,
9
Ponieważ .CompanyName jest traktowany jako selektor klasy.
cletus
2
Szybko patrząc na kod źródłowy, jest to celowa decyzja projektowa lub błąd. Wyrażenie regularne używane do identyfikacji selektorów identyfikatorów (o nazwie quickExpr) nie zawiera kropki jako prawidłowego znaku. Specyfikacja HTML na to pozwala.
Tomalak
5
Posiadanie selektora klasy na identyfikatorze jest prawdopodobnie przydatne. Wyobraź sobie, że masz element #menu na każdej stronie, ale chcesz go wyróżnić na jednej ze swoich stron. # menu.hideme na przykład? Marginal Wiem, ale jest ważny.
cletus
2
To wyraźnie najlepsza odpowiedź. Działa również z takimi zmiennymi: $ ("tr [id = '" + private_var + "']"). Css ("kolor tła", "#EEEEEE");
Steve K
33

Nie musisz niczego uciekać, jeśli używasz document.getElementById:

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

getElementById zakłada, że ​​dane wejściowe są tylko atrybutem id, więc kropka nie będzie interpretowana jako selektor klasy.

Mikser
źródło
Zgrabne rozwiązanie, działa również ładnie z dynamicznym identyfikatorem, który może zawierać kropki
Cookalino
17

Krótka odpowiedź : jeśli masz element o id = "foo.bar", możesz użyć selektora$("#foo\\.bar")

Dłuższa odpowiedź : jest to część dokumentacji jquery - selektory sekcji, które można znaleźć tutaj: http://api.jquery.com/category/selectors/

Odpowiedź na twoje pytanie znajduje się na początku dokumentacji:

Jeśli chcesz użyć dowolnego z metaznaków (np 
! "# $% & '() * +,. /:;? @ [\] ^` {|} ~) 
jako dosłowna część imienia, musisz uciec od postaci 
dwa odwrotne ukośniki: \\. Na przykład, jeśli masz element o id = "foo.bar",
możesz użyć selektora $ („# foo \\. bar”). Specyfikacja W3C CSS zawiera
pełny zestaw zasad dotyczących prawidłowych selektorów CSS. Przydatny jest również
wpis blogu autorstwa Mathiasa Bynensa na temat sekwencji ucieczki znaków CSS dla identyfikatorów.
oneiros
źródło
4
Zdajesz sobie sprawę, że to pytanie ma więcej niż trzy lata, a dokumentacja mogła być wtedy inna, prawda?
Reimius
9

wybór attr wydaje się odpowiedni, gdy twój identyfikator znajduje się w zmiennej:

var id_you_want='foo.bar';
$('[id="' + id_you_want + '"]');
biskup
źródło
4

Jest to udokumentowane w interfejsie API selektorów jQuery :

Użycie dowolnego z meta-znaków (na przykład !"#$%&'()*+,./:;<=>?@[\]^`{|}~) jako dosłowne część nazwy, należy uciec się z dwóch ukośników: \\. Na przykład element z id="foo.bar", może używać selektora $("#foo\\.bar").

Krótko mówiąc, prefiks .z \\.

$('#SearchBag\\.CompanyName')

Problem polega na tym, .że pasuje do klasy, więc $('#SearchBag.CompanyName')pasuje <div id="SearchBag" class="CompanyName">. Uciekający z \\.będzie traktowany jak normalny, .bez specjalnego znaczenia, pasujący do pożądanego identyfikatora.

Dotyczy to wszystkich znaków, !"#$%&'()*+,./:;<=>?@[\]^`{|}~które w innym przypadku miałyby specjalne znaczenie jako selektor w jQuery.

Jon Surrell
źródło
2

Chłopaki, którzy szukają bardziej ogólnego rozwiązania, znalazłem jedno rozwiązanie, które wstawia jeden ukośnik przed dowolnymi znakami specjalnymi, co rozwiązuje problemy związane z odzyskiwaniem nazwy i identyfikatora z div zawierającej znaki specjalne.

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

zwraca „Str1 \\. str2 \\% str3”

Mam nadzieję, że to się przyda!

Abhishek
źródło
1

Możesz użyć selektora atrybutów:

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

Lub możesz określić typ elementu:

$("input[id='SearchBag.CompanyName']");
ntroccoli
źródło