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/23034283/

相关文章:

javascript - 基于多个条件和多个数组进行过滤?

javascript - 如何将 Jquery $(document).scrollTop() 代码转换为 React JS?

html - 在一页上使用 2 个选项卡式内容部分

javascript - html5 音频在 ios safari 中不起作用

php - 为什么我的返回不起作用?

javascript - 将 javascript 对象变量从一个 HTML 页面传递到另一个 HTML 页面

javascript - 使用 Lodash 转换这个嵌套的 json 数据

javascript - 在 asp.net 中使用 jquery 验证插件时这可能吗

html - CSS:带透明框的彩色div

javascript - HTML:仍然无法从数据列表中选择数据属性吗?