jQuery SVG,为什么我不能 addClass?
我正在使用 jQuery SVG。我无法向对象添加或删除类。有人知道我的错误吗?
SVG:
<rect class="jimmy" id="p5" x="200" y="200" width="100" height="100" />
不会添加类的 jQuery:
$(".jimmy").click(function() {
$(this).addClass("clicked");
});
我知道 SVG 和 jQuery 可以很好地协同工作,因为我可以定位对象并在单击它时触发警报:
$(".jimmy").click(function() {
alert('Handler for .click() called.');
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
2016 年编辑:阅读接下来的两个答案。
element.classList.add('newclass')
在现代浏览器中工作JQuery(小于 3)无法将类添加到 SVG。
.attr()
适用于 SVG,因此如果您想依赖 jQuery:如果您不想依赖 jQuery:
Edit 2016: read the next two answers.
element.classList.add('newclass')
works in modern browsersJQuery (less than 3) can't add a class to an SVG.
.attr()
works with SVG, so if you want to depend on jQuery:And if you don't want to depend on jQuery:
DOM API 中有 element.classList 适用于两者HTML 和 SVG 元素。不需要 jQuery SVG 插件,甚至不需要 jQuery。
There is element.classList in the DOM API that works for both HTML and SVG elements. No need for jQuery SVG plugin or even jQuery.
jQuery 3 没有这个问题
jQuery 3.0 修订版 是:
此问题的一种解决方案是升级到 jQuery 3。它效果很好:
问题:
jQuery 类操作函数不适用于 SVG 元素的原因是 3.0 之前的 jQuery 版本使用
className
这些函数的属性。摘自 jQuery
attributes/classes.js
:这与 HTML 元素的预期行为相同,但是对于 SVG 元素
className
有点不同。对于 SVG 元素,className
不是字符串,而是SVGAnimatedString
。考虑以下代码:
如果运行此代码,您将在开发者控制台中看到类似以下内容的内容。
如果我们像 jQuery 那样将
SVGAnimatedString
对象转换为字符串,我们就会得到[object SVGAnimatedString]
,这就是 jQuery 失败的地方。jQuery SVG 插件如何处理此问题:
jQuery SVG 插件通过修补相关函数以添加 SVG 支持来解决此问题。
摘自 jQuery SVG
jquery.svgdom.js< /code>
:
该函数将检测是否元素是 SVG 元素,如果是,它将使用
SVGAnimatedString
对象的baseVal
属性(如果可用),然后再返回到class
属性。jQuery 在该问题上的历史立场:
jQuery 目前在其不会修复 页面上列出了此问题。这是相关部分。
显然,jQuery 考虑了 jQuery 核心范围之外的完整 SVG 支持,并且更适合插件。
jQuery 3 does not have this problem
One of the changes listed on the jQuery 3.0 revisions is:
One solution for this issue would be to upgrade to jQuery 3. It works great:
The Problem:
The reason the jQuery class manipulation functions do not work with the SVG elements is because jQuery versions prior to 3.0 use the
className
property for these functions.Excerpt from jQuery
attributes/classes.js
:This behaves as expected for HTML elements, but for SVG elements
className
is a little different. For an SVG element,className
is not a string, but an instance ofSVGAnimatedString
.Consider the following code:
If you run this code you will see something like the following in your developer console.
If we were to cast that
SVGAnimatedString
object to a string as jQuery does, we would have[object SVGAnimatedString]
, which is where jQuery fails.How the jQuery SVG plugin handles this:
The jQuery SVG plugin works around this by patching the relevant functions to add SVG support.
Excerpt from jQuery SVG
jquery.svgdom.js
:This function will detect if an element is an SVG element, and if it is it will use the
baseVal
property of theSVGAnimatedString
object if available, before falling back on theclass
attribute.jQuery's historical stance on the issue:
jQuery currently lists this issue on their Won’t Fix page. Here is the relevant parts.
Evidently jQuery considered full SVG support outside the scope of the jQuery core, and better suited for plugins.
如果您有动态类或者不知道可以应用哪些类,那么我认为这种方法是最好的方法:
If you have dynamic classes or don't know what classes could be already applied then this method I believe is the best approach:
根据上面的答案我创建了以下 API
Based on above answers I created the following API
加载
jquery.svg.js
后,您必须加载此文件:http://keith-wood.name/js/jquery.svgdom.js
。来源:http://keith-wood.name/svg.html#dom
工作示例:http://jsfiddle.net/74RbC/99/
After loading
jquery.svg.js
you must load this file:http://keith-wood.name/js/jquery.svgdom.js
.Source: http://keith-wood.name/svg.html#dom
Working example: http://jsfiddle.net/74RbC/99/
只需将缺少的原型构造函数添加到所有 SVG 节点即可:
然后您可以通过这种方式使用它,而不需要 jQuery:
所有功劳都归于 托德·摩托。
Just add the missing prototype constructor to all SVG nodes:
You can then use it this way without requiring jQuery:
All credit goes to Todd Moto.
jQuery 不支持 SVG 元素的类。您可以直接获取元素
$(el).get(0)
并使用classList
和添加/删除
。这也有一个技巧,最上面的 SVG 元素实际上是一个普通的 DOM 对象,并且可以像 jQuery 中的所有其他元素一样使用。在我的项目中,我创建了这个来满足我需要的内容,但 Mozilla 开发者网络 有一个可以作为替代方案的垫片。示例
另一种更困难的选择是使用 D3.js 作为选择器引擎。我的项目有用它构建的图表,因此它也在我的应用程序范围内。 D3 正确修改了普通 DOM 元素和 SVG 元素的类属性。尽管仅在这种情况下添加 D3 可能有点矫枉过正。
jQuery does not support the classes of SVG elements. You can get the element directly
$(el).get(0)
and useclassList
andadd / remove
. There is a trick with this too in that the topmost SVG element is actually a normal DOM object and can be used like every other element in jQuery. In my project I created this to take care of what I needed but the documentation provided on the Mozilla Developer Network has a shim that can be used as an alternative.example
An alternative all tougher is to use D3.js as your selector engine instead. My projects have charts that are built with it so it's also in my app scope. D3 correctly modifies the class attributes of vanilla DOM elements and SVG elements. Though adding D3 for just this case would likely be overkill.
jQuery 2.2 支持 SVG 类操作
jQuery 2.2 和 1.12 已发布帖子包含以下引用:
使用 jQuery 2.2.0 的示例
它测试:
如果你点击那个小方块,它会改变它的颜色,因为
class
属性是添加/删除。jQuery 2.2 supports SVG class manipulation
The jQuery 2.2 and 1.12 Released post includes the following quote:
Example using jQuery 2.2.0
It tests:
If you click on that small square, it will change its color because the
class
attribute is added / removed.我使用 Snap.svg 向 SVG 添加类。
http://snapsvg.io/docs/#Element.addClass
I use Snap.svg to add a class to and SVG.
http://snapsvg.io/docs/#Element.addClass
这是我相当不优雅但有效的代码,它处理以下问题(没有任何依赖项):
元素上不存在
classList
className< /code> 不代表 IE 中
元素上的
class
属性getAttribute()
和setAttribute()
实现它尽可能使用
classList
。代码:
用法示例:
Here is my rather inelegant but working code that deals with the following issues (without any dependencies):
classList
not existing on<svg>
elements in IEclassName
not representing theclass
attribute on<svg>
elements in IEgetAttribute()
andsetAttribute()
implementationsIt uses
classList
where possible.Code:
Example usage:
一种解决方法是将 addClass 添加到 svg 元素的容器中:
One workaround could be to addClass to a container of the svg element:
我在我的项目中写了这个,并且它有效......可能;)
示例
I wrote this in my project, and it works... probably;)
examples
受到上述答案的启发,尤其是 Sagar Gala,我创建了这个 API。如果您不想或无法升级您的 jquery 版本,您可以使用它。
Inspired by the answers above, especially by Sagar Gala, I've created this API. You may use it if you don't want or can't upgrade your jquery version.
或者当 JQ 在中间某处有一只猴子时,只使用老式 DOM 方法。
学习 DOM 人。即使在 2016 年的框架大会中,它也经常提供帮助。另外,如果你听到有人将 DOM 与程序集进行比较,请帮我踢掉他们。
Or just use old-school DOM methods when JQ has a monkey in the middle somewhere.
Learn the DOM people. Even in 2016's framework-palooza it helps quite regularly. Also, if you ever hear someone compare the DOM to assembly, kick them for me.