javascript - 是否可以使用 HTML 的 .querySelector() 通过 SVG 中的 xlink 属性进行选择?

标签 javascript html dom svg xlink

给定:

<body>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <a xlink:href="url"></a>
    </svg>
</body>

是否可以使用 HTML DOM 的 .querySelector().querySelectorAll() 通过其 xlink 的内容选择 SVG 内的链接:href 属性?

这个有效:

document.querySelector('a')                    // <a xlink:href="url"/>

这些不会:

document.querySelector('[href="url"]')         // null
document.querySelector('[xlink:href="url"]')   // Error: not a valid selector
document.querySelector('[xlink\:href="url"]')  // Error: not a valid selector
document.querySelector('[xlink\\:href="url"]') // null

有没有一种方法可以编写该属性选择器以使其“看到”xlink:href

最佳答案

查询选择器可以处理 namespace ,但它变得很棘手,因为

  1. 在 CSS 选择器中指定命名空间的语法与 html 不同;

  2. querySelector API 没有任何方法可以将命名空间前缀(如 xlink)分配给实际的命名空间(如 "http://www.w3.org/1999/xlink").

关于第一点,the relevant part of the CSS specs允许您指定 命名空间(默认)、特定命名空间或任何 命名空间:

@namespace foo "http://www.example.com";
[foo|att=val] { color: blue }
[*|att] { color: yellow }
[|att] { color: green }
[att] { color: green }

The first rule will match only elements with the attribute att in the "http://www.example.com" namespace with the value "val".

The second rule will match only elements with the attribute att regardless of the namespace of the attribute (including no namespace).

The last two rules are equivalent and will match only elements with the attribute att where the attribute is not in a namespace.

查看此 fiddle ,注意填充样式(默认、悬停和事件):
https://jsfiddle.net/eg43L/

Selectors API 采用 CSS 选择器语法,但没有等效于 @namespace 规则来定义命名空间。结果,selectors with namespaces are not valid but the wildcard namespace token is valid :

If the group of selectors include namespace prefixes that need to be resolved, the implementation must raise a SYNTAX_ERR exception ([DOM-LEVEL-3-CORE], section 1.4).

This specification does not provide support for resolving arbitrary namespace prefixes. However, support for a namespace prefix resolution mechanism may be considered for inclusion in a future version of this specification.

A namespace prefix needs to be resolved if the namespace component is neither empty (e.g. |div), representing the null namespace, or an asterisk (e.g. *|div), representing any namespace. Since the asterisk or empty namespace prefix do not need to be resolved, implementations that support the namespace syntax in Selectors must support these.

(加粗)

查看 the fiddle再次,这次要注意控制台输出。命令 document.querySelector('[*|href="#url"]') 返回您想要的元素。

最后一个警告:MDN告诉我 IE8- 不支持 CSS 命名空间,所以这可能对他们不起作用。


2015-01-31 更新:

正如@Netsi1964 在评论中指出的那样,这不适用于 HTML 5 文档中的自定义命名空间属性,因为 HTML 不支持 XML 命名空间。 (它适用于独立的 SVG 或其他 XML 文档,包括 XHTML。)

当 HTML5 解析器遇到类似 data:myAttribute="value" 的属性时,它会将其视为属性名称的单个字符串,包括 :。为了让事情变得更加困惑,它会自动将字符串小写。

要让 querySelector 选择这些属性,您必须将 data: 作为属性字符串的一部分。但是,由于 : 在 CSS 选择器中有特殊含义,您需要使用 \ 字符将其转义。由于您需要 \ 作为选择器的一部分通过,因此您需要在 JavaScript 中转义

因此,成功的调用如下所示:

document.querySelector('[data\\:myattribute="value"]');

为了使事情更合乎逻辑,我建议您对属性名称使用全部小写,因为 HTML 5 解析器无论如何都会转换它们。 Blink/Webkit 浏览器将自动小写您传递给 querySelector 的选择器,但这实际上是一个非常有问题的错误(意味着您永远无法选择具有混合大小写标签名称的 SVG 元素)。

但同样的解决方案是否适用于 xlink:href?不! HTML 5 解析器识别 SVG 标记中的 xlink:href,并将其正确解析为命名空间属性。

Here's the updated fiddle with additional tests .再次查看控制台输出以查看结果。在 Chrome 40、Firefox 35 和 IE 11 中测试;行为上的唯一区别是 Chrome 匹配混合大小写选择器。

关于javascript - 是否可以使用 HTML 的 .querySelector() 通过 SVG 中的 xlink 属性进行选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35864050/

相关文章:

html - 如何覆盖 css 属性?

html - 坚持修剪 CSS Sprite

javascript - 模拟点击动态添加的 DOM 中不存在的 div

javascript - Easy calculator 不工作 - 没有错误,但也没有结果

javascript - session cookie 在 document.cookie 中不可用

javascript - 如果函数是对象,那么函数体到哪里去了?

javascript - 在模态对话框/框中显示搜索结果

html - Bootstrap 导航栏在最小化浏览器时不起作用

javascript - 将 HTML 节点存储为 *object* 中的键

java - org.w3c.dom.ls.LSException 由 : java. lang.NegativeArraySizeException 引起