Is the css selector #<my-id> (supposed to be) 100% equivalent to [id=<my-id>] in jQuery?

Refresh

December 2018

Views

202 time

3

Some background: I have a site with a table displaying a list of entities. Using jQuery I make it possible to click on a row in the table which will load some extra data about the selected entity using AJAX. A new row is inserted into the table below the clicked row. This row contains more detailed information about the entity and is not really a row, just in HTML terms. It contains a whole bunch of data. When you click on another row, the details row currently shown will be hidden and the details row for the newly clicked entity is shown (loaded using AJAX if not loaded yet). No problems here.

On the details row there is also a select box. After loading the details row using Ajax, I want to bind the onchange event of the select. I do the following jQuery selection:

$("tr.entity_details[data-entity-id=" + entityId + "] select#SelectedDropDownValue")

The problem: This also works fine, except in some very particular case (which I havn't been able to completely define yet). Sometimes it doesn't select the select element. I use VS2010 to debug and entered these two items into my watch window:

$("tr.entity_details[data-entity-id=" + entityId + "] select#SelectedDropDownValue").length
$("tr.entity_details[data-entity-id=" + entityId + "] select[id=SelectedDropDownValue]").length

In the cases where the first one doesn't select anything, the second one does. This is really weird to me, because I thought that those two selectors are equivalent.

The situation when I could produce this is: I have two entities in my table.

  • I click on the bottom one first: no problem; then I click on the top one: no problem.
  • I click on the top one first: no problem; then I click on the bottom one: PROBLEM.

I have no idea what could cause this. I'm thinking maybe something with me inserting new rows and hiding them in javascript, causing the selection to go a bit off. But that would be a bug I suppose. Or maybe it has something to do with that the details row contains another table and the select is in side that inner table.

EDIT:

To add some more information. I tested this under IE9 and Chrome. I am developing an ASP.NET MVC 3 application using jQuery 1.5.1. The details row is generated by a partial view. In this partial view I use the Html Helper DropDownListFor. This helper generates the select element based on a C# property you pass to the function. It uses the property's name to generate a name and id for the element. This causes all the select elements in the page to have the same id. As some people already mentioned, that would probably be the cause.

3 answers

0

Идентификаторы часто злоупотребляют. Если вы инъекционные новые узлы DOM с JavaScript, там, наверное, момент, когда у вас есть узел внутри переменной. Вы можете просто подключить обработчик события к переменной; нет необходимости назначить идентификатор, впрыснуть узел в документ, а затем искать его по идентификатору.

4

Я работаю на сайт , который, ну, не соответствует. У нас есть много HTML - элементов , которые имеют один и тот же идентификатор. Я заметил , что $('#someid')хватает только первый элемент он находит с этим идентификатором , а $('[id="someid"]')грейферы все элементы с этим идентификатором.

3

При встрече строки , содержащей селектор только селектор ID, как $('#my-id'), JQuery каналов , которые непосредственно ID , document.getElementById()чтобы захватить первый элемент с этим идентификатором, без каких - либо дополнительных стадий. Это хорошо известный и хорошо документированный факт .

Если есть что - нибудь еще в селекторе вообще, JQuery пропускает document.getElementById()вызов полностью. Если браузер поддерживает document.querySelectorAll()и селектор поддерживается селектор CSS, то JQuery будет использовать этот API для запроса DOM никогда не используя свой собственный Sizzle двигателя. В противном случае, он откладывает шипеть.

Теперь, насколько CSS селекторы обеспокоены, селектор ID всегда должен соответствовать элементу , пока он идентифицируется этим идентификатором , независимо от того, говорит ли HTML , что это недопустимый иметь более одного такого элемента в том же документе. Смотрите этот ответ для объяснения. Я не совсем уверен , если Шипение ведет себя точно так же, но весьма вероятно , что нативный реализация будет вести себя как таковые. Конечно, так как разметка должна быть недействительны для того , чтобы сделать разницу, это не то , что вы должны полагаться на.

Селектор атрибута , как $('[id=my-id]'), с другой стороны, не несут ту же семантику, селектор ID. Это не означает «(или любой) элемент , который идентифицирован с помощью my-id »; скорее, он просто выбирает любой элемент с атрибутом , что случается, называется id, со значением my-id. Таким образом , в JQuery и CSS, а также независимо от семантики документа, она всегда соответствует любому элементу , пока он имеет этот атрибут и значение .

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