To what extent should I enforce a DOM element'

2019-09-08 08:03发布

问题:

I'm experiencing an issue which has two possible solutions. I am unsure which solution is 'more correct.'

I have a modal dialog which opens above a page. This dialog hosts an element with ID "foo".

Now, that is not an issue at all on its own. However, the non-dialog page has multiple tabs. One of these other tabs, deep down in some content, also has an ID "foo." This causes weird, intermittent issues depending on which "foo" is encountered first when traversing the DOM tree.

Unfortunately, both values are presenting exactly the same information in exactly the same way. The only difference is that one is being hosted inside of a dialog. The same model is being used -- thus the same ID is being generated by my ViewModel.

I can do one of two things:

  • Explicitly override one of these ID-creation methods to ensure that the ID generated in the dialog is unique when compared to that of the non-dialog.
  • Modify my jQuery search selector to only read from the dialog's form inward -- ensuring that the dialog will not capture unexpected DOM elements.

It would seem like the second idea is a better practice. I traverse less DOM nodes and don't have to hack anything in. However, to an unknowing developer, one could still accidentally re-introduce this issue by not starting searching from the proper area.

The same issue could be said to any developer working on our application, though. They would need to know explicitly to override the ID-creation of the ViewModel such that it does not create the same ID.

Is it ever acceptable to have repeating IDs if they're encapsulated in different forms? Where does the expectation of an ID being unique cease to make sense?

The ID is generated through MVC's EditorFor HTML Helper. I can override this in such a way that it generates a form-specific ID, but that was clearly not MVC's intention.

<%= Html.EditorFor(model => model.CustomerDisplayName) %>

UPDATE: It appears I should be enforcing the IDs uniqueness. However, ASP.NET MVC3 does not seem to provide an easy way of ensuring an ID is unique to the DOM. I can append on the form's ID, but that would generate huge IDs.. not sure if that is the best call. Any thoughts?

回答1:

Is it ever acceptable to have repeating IDs if they're encapsulated in different forms?

It is never acceptable, an ID should be unique. Otherwise your document is not valid.

Where does the expectation of an ID being unique cease to make sense?

The expectation of an ID being unique never ceases to make sense. It's part of the specs to have an unique ID per element.



回答2:

Do you have control over the IDs? If you do, perhaps ID isn't the most "proper" way to go about it. If you used a class instead, then:

$("#DialogID .foo")

would select it without the potential for foo being a duplicated ID. The above selector will restrict the search to within the specified dialog.



回答3:

To your question "To what extent should I enforce a DOM element's ID's uniqueness?", I boldly answer "You should NOT enforce unique IDs".

"Blasphemy!", I hear the Pharisees shout, vigorously waving the W3C bible. But I live in the real world.

1. It is impossible.
It is virtually impossible to create a large website that guarantees the uniqueness of IDs. Modern website are assembled from unrelated components, be it plug-ins, ads, widgets, you name it. All using their own set of IDs without knowing the existence of the other IDs on the page. Technically the unique IDs can only be enforced by using some sort of GUID. Of course, you could qualify, prefix or suffix your IDs with a classname or parent id and turn it into a long hierarchical composed ID. In fact this isn't that bad of a practice. But there will be no guarantee. Bottom line.

2. It's not your fault.
Repeat after me: "It's not my fault...it's not my fault...". I find it intellectually lazy and frustrating that the W3C team keeps this all too simplistic dogma alive, without looking at the real world. Do they suggest how to enforce this rule? Of course not - it's not their job. They only write the specs. But, if no one abides the law, either all of us are evil and doomed...or the law itself is at fault. So, once again, repeat after me: "It's not my fault...it's not my fault...".

3. A bit of creativity, perhaps?
Is there really no way to adjust that rigid rule and come up with a practical solution? Either in the specs or implemented in the browsers? A form of "id scope"? A namespace?

4. Darwin says "To survive, you need to adapt."
The only way to survive in the real world is to adapt to the real world, with all it's imperfections. Some survival advice (as suggested by others already):

  • The more unique you make your IDs, the less chance for errors.
  • When searching for IDs, assume that there may be duplicates on your page. So, limit your search as much as possible.

Now stone me, I dare you.



回答4:

You should enforce ID uniqueness 100%

The DOM requires that IDs be unique within it, else it is not valid, and as you've discovered you get strange and sometimes intermittent errors if you violate that requirement.

You can introduce some way to change the ID based on context, as you've mentioned, or you could take the approach of combining classes so you have, for example <div class="main foo"> and <div class="dialog foo"> where you can then use selectors to find "div.main.foo" or "div.dialog.foo" -- or get both by using just "div.foo"