默认情况下,JSF 会生成不可用的 ID,这些 ID 与 Web 标准的 CSS 部分不兼容

Posted

技术标签:

【中文标题】默认情况下,JSF 会生成不可用的 ID,这些 ID 与 Web 标准的 CSS 部分不兼容【英文标题】:By default, JSF generates unusable IDs, which are incompatible with the CSS part of web standards 【发布时间】:2012-05-30 09:32:18 【问题描述】:

一位活跃的 JSF(或 Primefaces)用户能否解释一下为什么默认情况下会发生这种情况,为什么没有人对此做任何事情:

<p:commandLink id="baz" update=":foo:boop" value="Example" />

生成的标记在没有 hack 的情况下无法在 javascript 或 CSS 中使用,通常应被视为无效:

<a href="javascript:void(0);" id=":foo:bar:baz">Example</a>

这里的id=":bar:baz:foo" 属性包含冒号,至少从 CSS 角度来看,这不是该属性的有效字符。

虽然根据规范该属性可能是有效的,但它无法与实际的 JavaScript 和 CSS 实现一起使用。

简而言之,JSF 中默认的id 属性生成无法用于前端开发。

【问题讨论】:

【参考方案1】:

之所以选择:,是因为这是唯一可以保证最终用户不会在 JSF 组件 ID(即 validated)中意外使用它的合理分隔符 可以通过 \ 转义它在 CSS 选择器中使用它。

注意html4 spec 表示冒号是idname 属性中的有效 值。因此,您对它与“网络标准”不兼容的抱怨无济于事。

IDNAME 标记必须以字母 ([A-Za-z]) 开头,后跟任意数量的字母、数字 ([0- 9])、连字符(“-”)、下划线(“_”)、冒号(“:”)和句点(“.”)。

因此,唯一的问题是: 是 CSS 选择器中需要转义的特殊字符。 JS 本身对冒号没有任何问题。 document.getElementById("foo:bar") 工作得非常好。唯一可能的问题是 jQuery,因为它使用 CSS 选择器语法。

如果您真的需要,那么您可以随时更改默认分隔符 :,方法是将 javax.faces.SEPARATOR_CHAR 上下文参数设置为例如-_ 如下。您只需要保证您自己在 JSF 组件 ID 中的任何地方都没有使用该字符(它尚未经过验证!)。

<context-param>
    <param-name>javax.faces.SEPARATOR_CHAR</param-name>
    <param-value>-</param-value>
</context-param>

顺便说一句,_ 的另一个缺点是它出现在 JSF 自动生成的 ID 中,例如 j_id1,因此您还应该确保在整个 JSF 页面中所有 NamingContainer 组件具有固定 ID 而不是自动生成的 ID。否则 JSF 将无法找到命名容器子项。

我只是不推荐它。从长远来看,它是令人困惑和脆弱的。再想一想,普通 JSF webapp 中的独特元素本身通常已经不在表单或表格中。它们通常只代表主要的布局方面。我想说,从一般的 HTML/CSS 角度来看,这是一个糟糕的设计。只需通过可重用的 CSS 类名而不是 ID 来选择它们。如果您确实需要,您可以随时将其包装在纯 HTML &lt;div&gt;&lt;span&gt; 中,其 ID 不会由 JSF 预先设置。

另见:

What are valid values for the id attribute in HTML? Is it possible to change the element id separator in JSF? How to select JSF components using jQuery? How to use JSF generated HTML element ID with colon ":" in CSS selectors? Integrate JavaScript in JSF composite component, the clean way

【讨论】:

@Daniel:这是 JS 特有的。 \ 又是 JS 字符串中的转义字符,因此您需要对其进行双重转义。 我验证了 w3.org/TR/html401/types.html#type-name 规范实际上确实将冒号列为有效字符。这并不能解决无法像 CSS 中那样引用 id 的问题。当前的 a 级浏览器实现似乎将第一个冒号之后的所有内容视为简单地被忽略的伪选择器,因此未应用整个选择器。 然后您应该阅读 CSS 规范如何处理 CSS 选择器中的冒号和句点等特殊字符。您需要通过 \ 来逃避它们。为什么 HTML 和 CSS“标准”不同步是另一个与 JSF 完全无关的问题。 另外,请参阅w3.org/TR/CSS21/syndata.html#value-def-identifier,它禁止在选择器中使用冒号。所以换句话说,在其默认设置下,JSF 对 CSS 开发人员来说是不可用的。 你喜欢不断重复这个:) 我也会重复自己:我从来没有遇到过严重的问题。我的普通 JSF webapp 中的独特元素本身永远不会出现在表单或表格中。它们仅代表主要布局方面。我想说,从一般的 HTML/CSS 角度来看,这是一个糟糕的设计。

以上是关于默认情况下,JSF 会生成不可用的 ID,这些 ID 与 Web 标准的 CSS 部分不兼容的主要内容,如果未能解决你的问题,请参考以下文章

Java Server Faces JSF - 谁负责自动生成的 id?

在 JSF 中生成自己的会话 ID

正则表达式模式修饰符

PHP正则表达式模式修饰符 /i, /is, /s, /isU等

蓝牙在 Mac 上不可用?7 方法尝试修复

升级到 jsf2 后的 ViewExpiredException