0

我遇到的问题有两种可能的解决方案。我不确定哪个解决方案“更正确”。

我有一个在页面上方打开的模式对话框。此对话框包含一个 ID 为“foo”的元素。

现在,这本身根本不是问题。但是,非对话框页面有多个选项卡。这些其他选项卡之一,在某些内容的深处,也有一个 ID“foo”。这会导致奇怪的间歇性问题,具体取决于遍历 DOM 树时首先遇到的“foo”。

不幸的是,这两个值都以完全相同的方式呈现完全相同的信息。唯一的区别是一个被托管在对话框中。使用了相同的模型——因此我的 ViewModel 生成了相同的 ID。

我可以做以下两件事之一:

  • 显式覆盖这些 ID 创建方法之一,以确保对话框中生成的 ID 与非对话框中生成的 ID 相比是唯一的。
  • 将我的 jQuery 搜索选择器修改为仅从对话框的表单向内读取——确保对话框不会捕获意外的 DOM 元素。

看起来第二个想法是一个更好的做法。我遍历的 DOM 节点更少,也不需要破解任何东西。但是,对于不知情的开发人员,由于没有从正确的区域开始搜索,仍然可能会意外地重新引入这个问题。

不过,同样的问题也适用于我们的应用程序的任何开发人员。他们需要明确知道要覆盖 ViewModel 的 ID 创建,这样它就不会创建相同的 ID。

如果以不同的形式封装重复的 ID,是否可以接受?对 ID 唯一性的期望在哪里不再有意义?

ID 是通过 MVC 的 EditorFor HTML Helper 生成的。我可以通过生成特定于表单的 ID 的方式覆盖它,但这显然不是 MVC 的意图。

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

更新:看来我应该强制执行 ID 的唯一性。但是,ASP.NET MVC3 似乎没有提供一种简单的方法来确保 ID 对 DOM 是唯一的。我可以在表单的 ID 上附加,但这会产生巨大的 ID.. 不确定这是否是最好的调用。有什么想法吗?

4

4 回答 4

7

如果以不同的形式封装重复的 ID,是否可以接受?

这是不可接受的,ID 应该是唯一的。否则您的文件无效。

对 ID 唯一性的期望在哪里不再有意义?

对 ID 唯一性的期望永远不会停止。每个元素都有一个唯一的 ID 是规范的一部分。

于 2013-01-23T01:05:39.203 回答
3

对于您的问题“我应该在多大程度上强制执行 DOM 元素的 ID 的唯一性? ”,我大胆地回答“您不应该强制执行唯一 ID ”。

“亵渎神明!”,我听到法利赛人大喊大叫,大力挥舞着W3C圣经。但我生活在现实世界中。

1.这是不可能的。
创建一个保证 ID 唯一性的大型网站几乎是不可能的。现代网站由不相关的组件组装而成,无论是插件、广告、小部件,应有尽有。所有人都使用自己的一组 ID,而不知道页面上是否存在其他 ID。从技术上讲,唯一 ID 只能通过使用某种 GUID 来强制执行。当然,您可以使用类名或父 ID 对您的 ID 进行限定、前缀或后缀,并将其变成一个长的分层组合 ID。事实上,这种做法并没有那么糟糕。但不会有任何保证。底线。

2. 这不是你的错。
跟着我重复:“这不是我的错……这不是我的错……”。我发现 W3C 团队保持这种过于简单的教条活着,而不看现实世界,这在智力上很懒惰和令人沮丧。他们是否建议如何执行此规则?当然不是——这不是他们的工作。他们只写规格。但是,如果没有人遵守法律,要么我们所有人都是邪恶的,注定要失败……要么是法律本身有错。所以,再一次,跟着我重复一遍:“这不是我的错……这不是我的错……”。

3. 有点创意,也许吧?
难道真的没有办法调整这个死板的规则,想出一个切实可行的解决方案吗?在规范中还是在浏览器中实现?“id 范围”的一种形式?命名空间?

4. 达尔文说“为了生存,你需要适应。”
在现实世界中生存的唯一方法是适应现实世界,尽管它的所有缺陷。一些生存建议(正如其他人已经建议的那样):

  • 您制作的 ID 越独特,出错的可能性就越小。
  • 搜索 ID 时,假设您的页面上可能存在重复项。因此,尽可能限制您的搜索。

现在用石头砸我,我敢。

于 2013-06-10T20:19:40.573 回答
3

您可以控制 ID 吗?如果你这样做了,也许 ID 不是最“正确”的方法。如果您改用类,则:

$("#DialogID .foo")

将选择它而不会foo成为重复 ID。上面的选择器会将搜索限制在指定的对话框内。

于 2013-01-23T01:03:06.427 回答
1

您应该 100% 强制执行 ID 唯一性

DOM 要求 ID 在其中是唯一的,否则它是无效的,并且正如您所发现的,如果您违反该要求,您会得到奇怪的,有时是间歇性的错误。

正如您所提到的,您可以引入一些基于上下文更改 ID 的方法,或者您可以采用组合类的方法,例如<div class="main foo"><div class="dialog foo">您可以在哪里使用选择器来查找“div.main.foo”或“div.dialog.foo”——或者只使用“div.foo”来获取两者

于 2013-01-23T01:10:55.257 回答